代码之家  ›  专栏  ›  技术社区  ›  jonb

通过JWT令牌改造到Rest服务器进行身份验证

  •  0
  • jonb  · 技术社区  · 7 年前

    我的服务器是基于Flask的,我的客户端是android studio,我正在使用改进版进行通信。

    问题是我无法在登录后将jwt令牌从android正确传递到服务器。

    有了邮递员,效果很好: {{url}}/auth-我以用户身份登录,并获取JWT令牌。 稍后,我将添加“Authorization”头,其值为“JWT{{JWT\u token}}”,并且 {{url}}/users/john-我在询问用户信息,收到后没有问题。

    public interface RunnerUserEndPoints {
    //    @Headers("Authorization")
        @GET("/users/{user}")
        Call<RunnerUser> getUser(@Header("Authorization") String authHeader, @Path("user") String user);
    

    调用本身(在发送之前,access\u令牌是正确的!):

    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 -
    

    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;
        }
    }
    

    实际上我真的被卡住了。在Reform的网站上尝试遵循所有教程,但没有成功。 我确信有一个简单的解决方案,我只需要添加值为“JWT”+access\u令牌的“Authorization”头,就像它在postman中工作一样,就这样!谢谢

    问题是在我的客户端中构建access\u令牌。 我做到了: JsonElement ans=响应。body()。get(“access_token”); access_token=“JWT”+ans.toString(); 我应该这么做: JsonElement ans=响应。body()。get(“access_token”); access_token=“JWT”+ans.getAsString();

    现在它发送“JWT ey…”

    1 回复  |  直到 7 年前
        1
  •  0
  •   rzetterberg    7 年前

    让我们开始看看我们对这个问题的了解。

    • 我们知道请求已发送
    • JWTError('无效的JWT头','不支持的授权类型')

    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]
    

    烧瓶jwt Authorization 标题值,并尝试将其一分为二。函数 split 可以用分隔符拆分字符串,但如果不使用分隔符调用它 it will use whitespace

    这告诉我们 烧瓶jwt 需要一个字符串,该字符串包含由空格(如空格)分隔的两部分,并且第一部分必须与我们使用的前缀匹配(在本例中) JWT

    如果我们回头看看您的客户机代码,我们可以看到,当您构建要放入 批准 标题之间没有添加空格 JWT公司 和实际令牌:

    apiService.getUser("JWT" + access_token, username);
    

    这是你应该做的:

    apiService.getUser("JWT " + access_token, username);
    

    注意后面的空格 ?