Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python OAuth2 server with social networks for a RESTfull API

I'm trying to implement OAuth2 server for a RESTfull API with a login option through social platforms (Github, Facebook, Instagram) using Python and Falcon web framework. But I've struggled to understand how this thing should work.

My current understanding led me to the following scheme: OAuth2 authorization scheme (using social platforms)

1.1. On the API side, I'm creating an endpoint /auth/login/github which basically will tell the mobile app to redirect the client to the Github.com authorization page - github.com/login/oauth/authorize 1.2. On the Github authorization page user will be presented with the following screen: Github authorization page 1.3. After pressing Authorize user will be taken to the page specified in the callback parameter (Github OAuth service configuration) with the newly granted temporary authorization code. In my case URL will look like: my.api.com/auth/callback/github?code=AUTH_CODE

2.1. After receiving a callback request, I'm parsing/extracting passed Authorization Code and query Github.com from the backend in order to redeem Authorization Code and get Access Token (sending POST request using my Client ID and Client Secret to github.com/login/oauth/access_token) 2.2. If everything was successful Github will reply to my POST request with the Access Token, which I can use to get user profile details (e.g. e-mail)

3.1. Now that I know that authorization through the Github was successful (because I got users' email) I can grant my own Access Token to that user, so he can query my API endpoints. I do this just by adding randomly generating OAuth2 Token and inserting it into my database, simultaneously returning same token to the user by redirecting him to the mobile app using deep links (e.g.: myapp://token). 3.2. Finally mobile app can query my API endpoints by adding the following header to each request Authorization: Bearer 0b79bab50daca910b000d4f1a2b675d604257e42

Does that make sense and is this the correct way of doing the social authorization for RESTfull API's?

I'm using Falcon as the web framework for this project and Authlib as the OAuth2 library.

like image 656
Vit D Avatar asked Oct 14 '18 20:10

Vit D


2 Answers

Its one way for sure. And it looks alright.

I'm going to make it simpler, and maybe its a bit clear whats happening.

1.1 [Mobile APP] redirects user to github.com/oauth/authorize?client_id=CLIENT_ID with the client id you registered with github

1.2 [Mobile APP] user comes via a redirect to fancy.app/callback/github?code=AUTH_CODE (this is the callback url you configure on github)
1.2.1 [Mobile APP] call your API endpoint with the AUTH_CODE

1.3 [API] confirm with github the AUTH_CODE is valid.

Up to this point we have user authentication; the user isn't a random guy, is user xxx on github.com and you have the information you requested.

Now, if you need to authorise this user on your API, after 1.3:

1.3.1 [API] generate a token
1.3.2 [API] store the token in some persistent storage
1.3.3 [API] define some expiration time for the token (actually the AUTH_CODE from github should have some expiration, use that)
1.3.4 [API] return the token to the mobile APP

This token we've generated is what the Mobile APP will use to authenticate the user on the API; no further calls to github (until expiration at least).

like image 100
Pedro Rodrigues Avatar answered Nov 04 '22 22:11

Pedro Rodrigues


1.1. On the API side, I'm creating an endpoint /auth/login/github which basically will tell the mobile app to redirect the client to the Github.com authorization page - github.com/login/oauth/authorize

Instead of hard coding /auth/login/github, how about making it a query parameter on your API so that you can quickly integrate separate OAuth2 providers (Google, Facebook, etc.)

Your endpoint URL would now look like /auth/login/?provider=github and your backend can provide the correct redirect url for the mobile app to go to. This means you can simply add new buttons for Facebook /auth/login/?provider=facebook and it would be minimal work.

When you receive the callback request, the URL may then look something like my.api.com/auth/callback/?provider=github&code=AUTH_CODE. You may also want to insert a new user record to your own database (if you have one), so you can prompt for extra info if required, I would do this in Django for example, since I require extra info on top of the data that is provided by third-party OAuth2 providers.

Overall, the approach looks sound.

like image 30
Graham Healy Avatar answered Nov 04 '22 22:11

Graham Healy