Google 云端点和 JWT
Google Cloud Endpoints and JWT
我有一个基于 Google Cloud Endpoints 的 API,我想使用 JWT(Json Web 令牌)进行授权。我可以为每个包含令牌的请求设置 Authorization header 并且它可以正常工作。我知道 Endpoints 将此 header 用于 Oauth2,这是我的问题。对自定义令牌使用 Authorization header 是否正确? 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 一起使用?
这些消息是由于端点库试图从 Authorization
header 中自动确定用户,以便它可以提供 endpoints.get_current_user
(source)。当 Authorization
header 包含作为有效 Google OAuth2 访问令牌或 Android ID 令牌的 Bearer 令牌时,它可以自动执行此操作。
简单地说,这不是错误,它只是无法自动处理您的授权header。没什么大不了的,因为你要通过 JWT 使用你自己的。
对于 JWT,您仍然可以使用 Authorization
header 并使用 PyJWT
自行验证 JWT(要安装 third-party 包,请参阅 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])
您可以使用 self-generated 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'
如果您不喜欢每次都看到关于无法验证令牌的端点日志,您可以使用自己的 header,例如 X-Auth
.
我有一个基于 Google Cloud Endpoints 的 API,我想使用 JWT(Json Web 令牌)进行授权。我可以为每个包含令牌的请求设置 Authorization header 并且它可以正常工作。我知道 Endpoints 将此 header 用于 Oauth2,这是我的问题。对自定义令牌使用 Authorization header 是否正确? 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 一起使用?
这些消息是由于端点库试图从 Authorization
header 中自动确定用户,以便它可以提供 endpoints.get_current_user
(source)。当 Authorization
header 包含作为有效 Google OAuth2 访问令牌或 Android ID 令牌的 Bearer 令牌时,它可以自动执行此操作。
简单地说,这不是错误,它只是无法自动处理您的授权header。没什么大不了的,因为你要通过 JWT 使用你自己的。
对于 JWT,您仍然可以使用 Authorization
header 并使用 PyJWT
自行验证 JWT(要安装 third-party 包,请参阅 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])
您可以使用 self-generated 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'
如果您不喜欢每次都看到关于无法验证令牌的端点日志,您可以使用自己的 header,例如 X-Auth
.