我的服务器是基于Flask的,我的客户端是android studio,我正在使用改造进行通信。
问题是登录后我无法正确地将jwt令牌从android传递到服务器。
随着邮递员的运作良好: {{url}} / auth - 我以用户身份登录,并获取JWT令牌。 后来我添加了“授权”标题,其值为“JWT {{jwt_token}}”和 {{url}} / users / john - 我要求提供用户信息,这些信息可以毫无问题地收到。
android studio的端点:
public interface RunnerUserEndPoints {
// @Headers("Authorization")
@GET("/users/{user}")
Call<RunnerUser> getUser(@Header("Authorization") String authHeader, @Path("user") String user);
调用本身(发送前access_token是正确的!):
final RunnerUserEndPoints apiService = APIClient.getClient().create(RunnerUserEndPoints.class);
Log.i("ACCESS","Going to send get request with access token: " + access_token);
Call<RunnerUser> call = apiService.getUser("JWT" + access_token, username);
Log.i("DEBUG","Got call at loadData");
call.enqueue(new Callback<RunnerUser>() {
@Override
public void onResponse(Call<RunnerUser> call, Response<RunnerUser> response) { ....
来自服务器的响应错误日志:
File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_restful\__init__.py", line 595, in dispatch_request
resp = meth(*args, **kwargs)
File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 176, in decorator
_jwt_required(realm or current_app.config['JWT_DEFAULT_REALM'])
File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 151, in _jwt_required
token = _jwt.request_callback()
File "C:\Users\Yonatan Bitton\RestfulEnv\lib\site-packages\flask_jwt\__init__.py", line 104, in _default_request_handler
raise JWTError('Invalid JWT header', 'Unsupported authorization type')
flask_jwt.JWTError: Invalid JWT header. Unsupported authorization type
10.0.0.6 - - [30/Sep/2017 01:46:11] "GET /users/john HTTP/1.1" 500 -
我的api-client
public class APIClient {
public static final String BASE_URL = "http://10.0.0.2:8000";
private static Retrofit retrofit = null;
public static Retrofit getClient(){
if (retrofit==null){
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
Log.i("DEBUG APIClient","CREATED CLIENT");
return retrofit;
}
}
其实我真的被困了。试图按照改造网站上的所有教程进行操作,但没有成功。 我确信有一个简单的解决方案,我只需要添加“授权”标题,其值为“JWT”+ access_token,就像它在邮递员中工作一样,就是这样!感谢。
编辑: 问题是在我的客户端构建access_token。 我做了: JsonElement ans = response.body()。get(“access_token”); access_token =“JWT”+ ans.toString(); 我应该做的: JsonElement ans = response.body()。get(“access_token”); access_token =“JWT”+ ans.getAsString();
所以在发送“JWT”之前......“”(Double“”) 现在它发送“JWT ey ......”
答案 0 :(得分:0)
让我们开始看看我们对这个问题的了解。
由于错误,我们知道JWT无效:
JWTError(&#39;无效的JWT标题&#39;,&#39;不支持的授权类型&#39;)
如果我们在flask_jwt
source code中查找该错误,我们可以看到这是我们提出错误的地方:
def _default_request_handler():
auth_header_value = request.headers.get('Authorization', None)
auth_header_prefix = current_app.config['JWT_AUTH_HEADER_PREFIX']
if not auth_header_value:
return
parts = auth_header_value.split()
if parts[0].lower() != auth_header_prefix.lower():
raise JWTError('Invalid JWT header', 'Unsupported authorization type')
elif len(parts) == 1:
raise JWTError('Invalid JWT header', 'Token missing')
elif len(parts) > 2:
raise JWTError('Invalid JWT header', 'Token contains spaces')
return parts[1]
基本上flask_jwt
获取Authorization
标头值并尝试将其拆分为两个。函数split
可以用分隔符分割字符串,但是如果你在没有分隔符it will use whitespace的情况下调用它。
这告诉我们flask_jwt
期望一个字符串包含由空格分隔的2个部分,例如空格,并且第一部分必须与我们使用的前缀匹配(在本例中为JWT
)。
如果我们返回并查看您的客户端代码,我们可以看到,当您构建要放入Authorization
标头的值时,您不会在JWT
和实际值之间添加空格令牌:
apiService.getUser("JWT" + access_token, username);
这是你应该做的:
apiService.getUser("JWT " + access_token, username);
注意JWT
之后的空格?