Google Cloud Endpoints和JWT

时间:2015-08-04 18:18:16

标签: google-app-engine google-cloud-endpoints

我有一个基于Google Cloud Endpoints的API,我想使用JWT(Json Web Tokens)进行授权。我可以为每个包含令牌的请求设置Authorization标头,它可以正常工作。我知道Endpoints在Oauth2中使用了这个标题,这是我的问题。使用自定义令牌的授权标头是否正确? GAE日志:

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.

看起来GAE试图将此令牌读作oauth令牌并且它不好,对吧?也许我应该在URL中发送我的令牌?像app-id.appspot.com/_ah/api/my_app/v1/users/get?jwt=TOKEN之类的东西。也许我不应该将JWT与Google Cloud Endpoints结合使用?

1 个答案:

答案 0 :(得分:6)

这些消息是由于端点库试图从Authorization标头自动确定用户,因此它可以提供endpoints.get_current_usersource)。当Authorization标头包含有效Google OAuth2访问令牌或Android ID令牌的Bearer令牌时,它可以自动执行此操作。

简而言之,这不是错误,它只是无法自动处理您的授权标头。没有什么大不了的,因为你自己通过JWT。

对于JWT,您仍然可以使用Authorization标头并使用PyJWT自行验证JWT(要安装第三方软件包,请参阅here)。

这是一个完整的样本:

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])

您可以使用自生成的jwt令牌对此进行测试:

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

然后使用httpie发出请求:

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

如果您不希望每次都看到端点日志无法验证令牌,您可以使用自己的标头,例如X-Auth