An example Google AppEngine project using Cloud Endpoints and custom authentication.
The supported workflow:
- A mobile client authenticates via a third-party provider using a native SDK flow, in this case with Facebook.
- The Facebook access token is sent to the AppEngine app, who verifies and returns its own access token in response, creating a new User entity if necessary.
- The client includes that token in each endpoints service request using in the
Authorization
header. - The endpoints method uses the access token to retrieve the authenticated user.
This is intentionally a narrow use case, but should help inspire ideas on different approaches as well.
- webapp2 is used for the access token exchange handler
- webapp2_extras.appengine provides a custom User model
- simpleauth is included a submodule and is used to verify provider access tokens
- Check out the project and submodules
git clone git@github.com:loudnate/appengine-endpoints-auth-example.git
git submodule update
- Generate a client application for your endpoints
- Include the Facebook SDK and implement a login flow
- Exchange the Facebook access token for one provided by your app
POST /oauth2/access_token HTTP/1.1
Host: https://your-app-id.appspot.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
x_access_token=facebook-access-token&x_provider=facebook
{
"token_type": "Bearer",
"refresh_token": "6oqmYZSaQ72nZfEYlD5PZF",
"access_token": "nc7Omfm4vgP0swqodJyDeN",
"expires_in": 31536000
}
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"x_access_token": @"facebook-access-token", @"x_provider": @"facebook"};
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:@"https://your-app-id.appspot.com/oauth2/access_token"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// ...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ...
}];
- Store the credentials somewhere appropriate and send them with each endpoints service request
GTLServiceHelloworld *service = [[GTLServiceHelloworld alloc] init];
NSString *authHeaderValue = [NSString stringWithFormat:@"%@ %@", responseObject[@"token_type"], responseObject[@"access_token"]];
service.additionalHTTPHeaders = @{@"Authorization": authHeaderValue};