pinoyyid
pinoyyid

Reputation: 22286

How do I test Cloud Endpoints with Oauth on devserver

My app uses Oauthed Cloud Endpoints and is working fine in production.

My problem is that on the local devserver, my User user is always set to [email protected], even though I've gone through the usual auth, access code, etc etc etc and have a valid authed user.

I get that [email protected] is useful to test oauth endpoints before I have oauth working properly, but since my app is working I'd rather see the actual user there.

To be specific, my endpoint method is

@ApiMethod(name = "insertEmp"), etc
public Emp insertEmp(User user, Emp emp) {
      System.out.println(user.getEmail());  // (A) log "appengine" email
      System.out.println(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(); // (B) log authed email

       ...

When deployed, everything is fine, and both (A) and (B) log the authenticated user ([email protected]).

When testing on my local devserver, (A) always logs "[email protected]", even though I have gone through the Oauth sequence and have a valid, authenticated user, and (B) logs [email protected]. So I can do hi-fidelity testing, I need the User to be the real authenticated user.

So in simple terms, how do I get (A) and (B) to be the same?

Upvotes: 13

Views: 2771

Answers (7)

user1796637
user1796637

Reputation: 41

Using the go runtime I have resorted to this function to obtain a User that is functional on both the dev server and production:

func currentUser(c context.Context) *user.User {
    const scope = "https://www.googleapis.com/auth/userinfo.email"
    const devClient = "123456789.apps.googleusercontent.com"

    allowedClients := map[string]bool{
        "client-id-here.apps.googleusercontent.com": true,
        devClient: true,                // dev server
    }

    usr, err := user.CurrentOAuth(c, scope)
    if err != nil {
        log.Printf("Warning: Could not get current user: %s", err)
        return nil
    }

    if !allowedClients[usr.ClientID] {
        log.Printf("Warning: Unauthorized client connecting with the server: %s", usr.ClientID)
        return nil
    }

    if (usr.ClientID == devClient) {
        usr = user.Current(c)           // replace with a more interesting user for dev server
    }
    return usr
}

This will use the dev server login information entered using http://localhost:8080/_ah/login

Upvotes: 0

gambettoturco
gambettoturco

Reputation: 62

It's not possible. I use another endpoint to replace user_id in current session.

Upvotes: -1

Rahul
Rahul

Reputation: 49

I replaced the Oauth2 user ([email protected]) with user from UserFactory and it works fine. I use this method to validate user for all API authenticated API requests.

public static User isAuthenticated(User user) throws OAuthRequestException{

    if(user == null){
        throw new OAuthRequestException("Please login before making requests");
    } 
    if(SystemProperty.environment.value() ==
            SystemProperty.Environment.Value.Development && "[email protected]".equalsIgnoreCase(user.getEmail()) ) {

        //Replace the user from the user factory here.
        user = UserServiceFactory.getUserService().getCurrentUser();

    }
    return user;

}

Upvotes: 0

pinoyyid
pinoyyid

Reputation: 22286

It seems it can't be done. I've ended up coding around it by putting the following code at the top of my Endpoint methods.

if ("[email protected]".equalsIgnoreCase(user.getEmail()) {
    user = new User(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(),"foo");
}

So now, even on devserver, the User email matches the Oauth email.

Upvotes: 4

Lars Christoffersen
Lars Christoffersen

Reputation: 1739

In your endpoint API you need this

ApiMethod ( name="YourEndPointName", path="yourPath",
            clientIds={"YourId.apps.googleusercontent.com"},
                    scopes =   { "https://www.googleapis.com/auth/userinfo.profile" })

Then in the called method, you will have a User object from the GAPI. Use this to get the actual email from the google User object like this

public myEndPointMethod( Foo foo, User user ){
    email = user.getEmail();
}

Upvotes: 0

Sca09
Sca09

Reputation: 381

The thing is that when you are doing the authentication in local, you are not doing it through the Google servers so authenticating your user is something that actually is not happening in local.

Google always provides the [email protected] user when you try to simulate the log in, it happens basically in all the services, like when you provide a log in through your Google Account in any web site (for instance using GWT and App Engine).

What can be different in your site if you test with your real user or you consider [email protected] user as your user?

Upvotes: 0

Lars Christoffersen
Lars Christoffersen

Reputation: 1739

This is not so easy. You'll have to make your settings in the APIs Console. Here you will be able to add "localhost" (http://localhost/) Then you can authenticate, through Google, even though you are running you application on your localhost for development. I have used it extensively, and it works OK Links: https://code.google.com/apis/console/ Just remember the ID's you use here is completely independent of you appengine ID. Took me a few hours to figure that one out.

Upvotes: 2

Related Questions