Google OAuth2.0¶
Google OAuth 2.0 Quick Start¶
Basic Usage:
oauth_options = {
"client_id": "<CLIENT_ID>",
"client_secret": "<CLIENT_SECRET>",
"redirect_uri": "http://localhost:3000",
"tablename": "users",
"email_field": "email",
"expires_in": 3600,
}
jwt_routes.init_app(app, google_oauth=oauth_options)
Now your front end needs a token. Create an endpoint & return a new access token from the clients header code. For Example:
from flask import request
@app.routes("/login", methods=["POST"])
def login():
jwt_routes.google.oauth_login(request) # Pass in Flask's request
Now, the next time your front-end requests authorised resources flask-jwt-router will authenticate with this access token until it expires.
Flask-JWT-Router OAuth 2.0 Flow Explained¶
Client¶
If you’re client is a React application, we strongly recommend you use React-Google-Oauth2 https://github.com/joegasewicz/react-google-oauth2.0 It’s maintain by Flask-JWT-Router’s author, so if fully compatible.
The client is your front end application, this could be another Flask api that renders jinja2 html templates or a React / Angular / Vue.js single page application. There are 2 steps that your client must successfully complete before Flask-JWT-Router can return a valid Google OAuth 2.0 access token.
The client must redirect the user to Googles sign in page. The user will then be asked to accept any extra scopes (Only required for advance access to Google Apis). If the user successfully signs in then Google will return a code to the client.
The client must now make a
POST
http request to your Flask api with Google’s code in the X-Auth-Token header. For examplecurl -X POST -H “X-Auth-Token”: “<YOUR_GOOGLE_OAUTH2.0_CODE>” http://localhost:5000/login
Server¶
The server is your Flask app. Now that your client has a code & has made the request to
the server, we must provide a Flask view handler to exchange the client’s code for an
access token. Flask-JWT-Router has public method (See oauth_login
)
that takes Flask’s request as a single argument. If the Google OAuth2.0 code is valid, then a valid
access token will be returned in the response body.
For example:
from flask import request
@app.routes("/login", methods=["POST"])
def login():
data = jwt_routes.google.oauth_login(request) # Pass in Flask's request
return data, 200
# Returns:
# {
# "access_token": "GOOGLE_OAUTH2.0_ACCESS_TOKEN>
# }
Each time the client requires any authorised resources in your Flask app, it must make all requests will the following headers:
{
"X-Auth-Token" : "<YOUR_GOOGLE_OAUTH2.0_CODE>"
}
This will allow the user to gain access to your Flask’s app resources until the access token’s expire time has ended. The client should then decide whether to redirect the user to Google’s login screen.
If your app requires multiple redirect uri’s then you can use the redirect_uri kwarg to assign a uri for the current request handler. For example:
data = jwt_routes.google.oauth_login(request, redirect="http://another_redirect.com")
Testing¶
Testing OAuth2.0 in a Flask app is non-trivial, especially if you rely on Flask-JWT-Router to append your user onto Flask’s global context (or g). Therefore we have provided a utility method that returns a headers Dict that you can then use in your test view handler request. This example is using the Pytest library:
@pytest.fixture()
def client():
# See https://flask.palletsprojects.com/en/1.1.x/testing/ for details
def test_blogs(client):
user_headers = jwt_routes.google.create_test_headers(email="user@gmail.com")
rv = client.get("/blogs", headers=user_headers)
If you are not running a db in your tests, then you can use the entity kwarg. For example:
# user is an instantiated SqlAlchemy object
user_headers = jwt_routes.google.create_test_headers(email="user@gmail.com", entity=user)
# user_headers: { "X-Auth-Token": "Bearer user@gmail.com" }
If you require more than one request to a Flask view handler in a single unit test, then set the scope kwarg to application. (Default is function). If you are testing different entities within a single unit test method or function then you must pass in your entity. For example:
my_entity = User(email="user@gmail.com") # If you're testing against a real db, make sure this is an entry in the db
_ = jwt_routes.google.create_test_headers(email="user@gmail.com", scope="application", entity=my_entity)
-
class
flask_jwt_router.oauth2.google.
Google
(http)[source]¶ Call to a Google API to authenticate via access_token
-
client_id
: str¶ Found in https://console.developers.google.com/apis/dashboard > Credentials > OAuth 2.0 Client IDs
-
client_secret
: str¶ Found in https://console.developers.google.com/apis/dashboard > Credentials > OAuth 2.0 Client IDs Never share this value with any client side code!
-
email_field
: str¶ Value of the email field column in the
-
expires_in
: int = None¶ OPTIONAL. Default is 7 days. The lifetime in seconds of the access token. For example, the value “3600” denotes that the access token will expire in one hour from the time the response was generated.
-
grant_type
= 'authorization_code'¶ As defined in https://tools.ietf.org/html/rfc6749#section-4.1.3 Value MUST be set to “authorization_code”.
-
header_name
: str = 'X-Auth-Token'¶ The X header name used for the Google Auth2.0 Strategy (subsequent strategies should be “X-<STRATEGY_NAME>-Token”
-
oauth_login
(request: flask_jwt_router.oauth2._base._FlaskRequestType, **kwargs) → Dict[source]¶ - Parameters
request – Flask request object
- Key redirect_uri
If your app requires multiple redirect uri’s then
you can use the redirect_uri kwarg to assign a uri for the current request handler. For example:
data = jwt_routes.google.oauth_login(request, redirect="http://another_redirect.com")
- Return Dict
-
redirect_uri
: str¶ This field must match exactly the client side redirect string you have defined in Google developer Credentials page: See https://console.developers.google.com/apis/dashboard > Credentials > OAuth 2.0 Client IDs. Click thru & match from the lists of the redirect domains
-
tablename
: str¶ Value of SQLAlchemy’s __tablename__ attribute