Authenticating Users with Java for the App Engine Standard Environment

This part of the Bookshelf tutorial for Java shows how to create a sign-in flow for users who have Google accounts, and how to use profile information to provide users with personalized functionality, using the App Engine Users service.

This page is part of a multi-page tutorial. To start from the beginning and see instructions for setting up, go to Java Bookshelf App.

Running the app on your local machine

To run the app locally:

  1. In the getting-started-java/bookshelf-standard/4-auth directory, enter this command to start a local web server:

    mvn -Plocal clean appengine:devserver -Dbookshelf.bucket=[YOUR-BUCKET]
    Replace [YOUR-BUCKET] with your bucket name.
  2. In your web browser, navigate to http://localhost:8080

Now you can browse the app's web pages, sign in using your Google account, add books, and see the books you've added using the My Books link in the top navigation bar.

Deploying the app to the App Engine standard environment

To deploy to the App Engine standard environment:

  1. Make sure you have fully exercised the Bookshelf application locally, especially creating at least one book and then clicking My Books. This creates a required Cloud Datastore index that is uploaded with Bookshelf. Note that building the application using clean deletes that local index, so be sure to do this on the build of the application that you are going to deploy.
  2. In the getting-started-java/bookshelf-standard/4-auth directory, enter this command to deploy the app:
    mvn appengine:update -Dappengine.appId=[YOUR-PROJECT-ID] -Dappengine.version=[YOUR-VERSION] -Dbookshelf.bucket=[YOUR-BUCKET].appspot.com
    Replace [YOUR-PROJECT-ID] with your project ID and [YOUR-VERSION] with your version, for example, 1, or 2, or some other string value you want to use.
  3. In your web browser, enter this address:
    https://[YOUR-PROJECT-ID].appspot.com
    Replace [YOUR-PROJECT-ID] with your project ID.

After you update your app, you can redeploy the updated version by entering the same command you used to deploy the app the first time, specifying the same project ID and version: this overwrites the currently deployed app. If you specify a different version string in the update command line, the new deployment creates a new version of your app and promotes it to be the currently serving version.

You can reduce costs by deleting the non-serving versions of your app.

To delete an app version:

  1. In the Cloud Platform Console, go to the App Engine Versions page.

    Go to the Versions page

  2. Click the checkbox next to the non-default app version you want to delete.
  3. Click the Delete button at the top of the page to delete the app version.

For complete information about cleaning up billable resources, see the Cleaning up section in the final step of this tutorial.

Application structure

The following diagram shows the application's components and how they connect to one another.

Auth sample structure

Understanding the code

This section walks you through the application code and explains how it works.

The LoginServlet is invoked when the user clicks Login. It does the following:

  1. Determines whether the user is currently logged into a Google account, and if so, saves the user email and ID information in the current session.

  2. If the user isn't logged into a Google account, the user is redirected to the Google account login page. Note that the App Engine Users service handles most of the complexity of user login for you.

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {

    UserService userService = UserServiceFactory.getUserService();
    if (userService.isUserLoggedIn()) {
      // Save the relevant profile info and store it in the session.
      User user = userService.getCurrentUser();
      req.getSession().setAttribute("userEmail", user.getEmail());
      req.getSession().setAttribute("userId", user.getUserId());

      String destination = (String) req.getSession().getAttribute("loginDestination");
      if (destination == null) {
        destination = "/books";
      }

      resp.sendRedirect(destination);
    } else {
      resp.sendRedirect(userService.createLoginURL("/login"));
    }
  }
}

The LogoutServlet deletes the session and creates a new one:

@SuppressWarnings("serial")
public class LogoutServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    // you can also make an authenticated request to logout, but here we choose to
    // simply delete the session variables for simplicity
    HttpSession session =  req.getSession(false);
    if (session != null) {
      session.invalidate();
    }
    // rebuild session
    req.getSession();
  }
}

Send feedback about...