Defining the Endpoints
This is where the rubber hits the road. It’s time to define the endpoints for the demo app. There are four of them. First is a homepage. It will be mapped to the URL
/. Second is the login endpoint, mapped to the URL
Third is the logout endpoint, mapped to the URL
/logout. And the final endpoint is the callback, which Google will redirect the user to after they’ve been authenticated. Recall the URL of
/login/callback was given to Google during the registration process.
Start off with the homepage. The
route decorator on the Flask
app object accepts the URL that will be mapped to a handler function.
The function itself just returns some HTML. It will look at the
current_user object from
current_user is an instance of the
.is_authenticated property of the
User class will be
True when a user is logged in. So if there’s a user logged in, display the profile information for the user.
Otherwise, display a link to the login page. Speaking of the
/login route, it does the heavy lifting of kicking off the OAuth 2 flow. But first, create a helper function that will get the provider configuration from the
.well-known/ discovery endpoint. Here, you can see the power of the
requests module. To make a basic
GET request, call the
get() function and pass it a URL.
The response will be in JSON format. The
login() handler will be mapped to the
/login route. Get the authorization endpoint from the provider configuration.
01:40 Use the OAuth client class to construct a URL which will start the Google login. Notice that it includes the authorization endpoint from the provider configuration, the redirect URI you registered with Google, and a list of scopes, which are the types of data your app is requesting access to. The scopes are displayed to the user on the consent screen. Redirect the user to the URL, which will request them to log in with their Google account.
You’ll see this in a minute when you run the app, but after logging in, the user will be taken to the consent screen. Assuming they authorize your app, Google will then redirect to the callback URL
/login/callback. Define that route in the handler next.
Remember that Google will send an authorization code back to your app. It will be in the query string as the key
"code". Your app needs to send that code back to Google and exchange it for tokens.
02:35 First, retrieve the token endpoint from the provider configuration.
02:40 Use the OAuth2 client again to construct a URL to call and get the token.
Now, call the token URL to generate and receive the actual token. Notice that this is a
POST request. Also, this is where you provide the client ID and secret to verify the identity of your app.
03:02 The token itself will be in JSON format. The OAuth client can then parse the tokens out of the JSON data. Armed with a token, you can use it to get the profile information to show for authenticated users on the homepage.
03:16 The URL to get the profile is also in the provider configuration. Construct a URL that uses the token and call it to get a response with the profile data. Congratulations!
03:30 If you get this far, the hard work is done. All that is left is to pull the profile data out of the response. The profile data is available after a user has verified their email address, so check for that first. If so, get the JSON from the user response and pull the individual profile values out.
If the email address is not verified, return an error and a status code of
400 for a
Use the profile values to create a new
User and insert it into the database, if it does not exist.
Finally, you can log the user into your app… and redirect the user to the homepage. The
url_for() function accepts the name of a request handler function.
04:19 It will generate a URL for that function based on the route that decorates it. You’re almost done. What comes up must eventually come down, and what is logged in must eventually get logged out. Create a logout route and handler function.
logout_user() function will log out the current user. After logout, redirect the user back to the homepage. The
logout() handler should only be valid for logged in users.
@login_required decorator to the handler function. If a user tries to access the URL without logging in, they will be redirected to the login page. To run the application, add an entry point and then call the
.run() method on the Flask app.
This will start the server on the
localhost address and listen on port
5000. But Google requires the callback endpoint to use SSL. Add the
ssl_context keyword argument to the
.run() method to enable SSL.
Become a Member to join the conversation.
ynotmarygrace on Feb. 8, 2021
Why is it that
createis not available for