Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Defining the Endpoints

00:00 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 /login.

00:16 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.

00:34 Start off with the homepage. The route decorator on the Flask app object accepts the URL that will be mapped to a handler function.

00:43 The function itself just returns some HTML. It will look at the current_user object from Flask-Login. The current_user is an instance of the User class.

00:54 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.

01:04 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.

01:28 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.

02:07 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.

02:23 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.

02:47 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.

03:50 If the email address is not verified, return an error and a status code of 400 for a Bad Request.

03:58 Use the profile values to create a new User and insert it into the database, if it does not exist.

04:07 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.

04:34 The 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.

04:47 Add the @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.

05:03 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.

05:18 Next, you can finally run the demo app.

ynotmarygrace on Feb. 8, 2021

Why is it that create is not available for User object?

Become a Member to join the conversation.