What user is provided by App Engine Devserver

399 views Asked by At
2

There are 2 answers

0
Aaron Roller On

Deploy this Api class in an endpoints project:

import com.google.api.server.spi.Constant;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.appengine.api.oauth.OAuthRequestException;
import com.google.appengine.api.oauth.OAuthServiceFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;

@Api(clientIds = Constant.API_EXPLORER_CLIENT_ID)
public class AuthEndpoints {

@ApiMethod
public User userFromUserService() {
    return UserServiceFactory.getUserService().getCurrentUser();
}

@ApiMethod
public User userFromParameter(User user) {
    return user;
}

@ApiMethod
public User userFromOAuthService() throws OAuthRequestException {
    return OAuthServiceFactory.getOAuthService().getCurrentUser();
}
}

Summary

  • OAuthService provides userId=0 all the time
  • UserService provides userId=185804764220139124118 if authenticated
  • Endpoints User Injection provides userId=0 if authorized, null if not

Details

  • No authentication, no OAuth Authorization

    • userFromUserService returns null
    • userFromParameter returns null
    • userFromOAuthService returns userId=0
  • API Explorer OAuth authorized (default credentials)

    • userFromService returns null
    • userFromParmeter returns userId=0
    • userFromOAuthService returns userId=0
  • Devserver login via /_ah/login (default credentials)

    • userFromService returns userId = 185804764220139124118
    • userFromParameter returns userId = 0 (oauth provided)
    • userFromOAuthService returns userId=0

Returning null from endpoints results in http status = 204. Null is the correct endpoints behavior per the docs.

If an incoming client request has no authorization token or an invalid one, user is null. In your code, you need to check whether user is null and do ONE of the following, depending on the condition: 1. If the user is non-null, perform the authorized action. 2. If the user is null, throw an OAuthRequestException. 3. Alternatively, if the user is null, perform some action for an unauthorized client access if some sort of unauthorized access is desired.

OAuthService docs explain returning user zero is the expected behavior.

On the local development server, oauth.getCurrentUser() always returns a User object with email set to "[email protected]" and user ID set to 0 regardless of whether or not a valid OAuth request was made.

Two accounts returned:

{
 "email": "[email protected]",
 "authDomain": "gmail.com",
 "userId": "0",
 "nickname": "[email protected]"
}

{
 "email": "[email protected]",
 "authDomain": "gmail.com",
 "userId": "185804764220139124118",
 "nickname": "[email protected]"
 }

These tests were run using appengine-maven-plugin:1.9.21:devserver

Conclusion

  • Don't expect your user login (web.xml protected) to produce the same user as OAuth via Endpoints.
  • Use User Injection if you have an endpoint that may provide a valid response even if no authentication is provided
    • You can't rely on OAuthService to indicate if no authorization is provided (on the dev server)

I answered my own question, but I will ask why does it need to be this confusing?

0
Chandan Reddy On

They return the user object corresponds to the currently logged in user.
I there is no user logged in, they will return null

You can redirect the user to login page by redirecting to url retured by UserService.createLoginUrl()

This works same in production and dev server. only difference is dev server doesn't validate the user credentials. It asks for email only, no passsword required.