Google Cloud Endpoints and JWT

一曲冷凌霜 提交于 2019-12-05 04:51:40

问题


I have an API based on Google Cloud Endpoints and I want to use JWT (Json Web Tokens) for authorization. I can set Authorization header for every request which contains token and it works correctly. I know that Endpoints uses this header for Oauth2 and here is my question. Is it correct to use Authorization header for custom token? GAE logs:

D 12:38:44.375 Checking for id_token.
D 12:38:44.376 id_token verification failed: Unexpected encryption algorithm: u'HS256'
D 12:38:44.376 Checking for oauth token.
D 12:38:44.384 Oauth framework user didn't match oauth token user.

It looks like GAE tries to read this token as oauth token and it is not good, right? Maybe I should send my token in URL? Something like app-id.appspot.com/_ah/api/my_app/v1/users/get?jwt=TOKEN. Maybe I shouldn't use JWT with Google Cloud Endpoints?


回答1:


These messages are due to the endpoints library attempting to automatically determine the user from the Authorization header so that it can provide endpoints.get_current_user (source). It can do this automatically when the Authorization header contains a Bearer token that is a valid Google OAuth2 access token or an Android ID token.

Simply put, this is not an error, it's just not able to automatically process your Authorization header. No big deal since you're going with your own via JWT.

For JWTs, you can still use the Authorization header and validate the JWT yourself using PyJWT (to install third-party packages, see here).

Here's a complete sample:

import logging

import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote

import jwt


class TestMessage(messages.Message):
    message = messages.StringField(1)


@endpoints.api(name='example', version='v1')
class ExampleApi(remote.Service):
    @endpoints.method(message_types.VoidMessage, TestMessage, http_method='GET')
    def auth(self, unused_request):

        # Get the HTTP Authorization header.
        auth_header = self.request_state.headers.get('authorization')
        if not auth_header:
            raise endpoints.UnauthorizedException("No authorization header.")

        # Get the encoded jwt token.
        auth_token = auth_header.split(' ').pop()

        # Decode and verify the token
        try:
            payload = jwt.decode(auth_token, 'secret')
            # Do your own check here.
            logging.info(payload)
        except jwt.InvalidTokenError:
            raise endpoints.UnauthorizedException("Token validation failed.")

        return TestMessage(message='OK')


app = endpoints.api_server([ExampleApi])

You can test this with a self-generated jwt token:

$ python -c "import jwt; print jwt.encode({'some': 'data'}, 'secret')"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoiZGF0YSJ9.g1aG08iQyPPwCTJHCxRrkKoYmLiHbBNdarcBQkCPMG4

Then use httpie to make a request:

$ http GET :8080/_ah/api/example/v1/auth Authorization:'Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoiZGF0YSJ9.g1aG08iQyPPwCTJHCxRrkKoYmLiHbBNdarcBQkCPMG4'

If you don't like seeing the endpoints logs about not being able to validate the token every time, you can use your own header, like X-Auth.



来源:https://stackoverflow.com/questions/31816453/google-cloud-endpoints-and-jwt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!