【问题标题】:devise_token_auth always returns 401 Unauthorizeddevise_token_auth 总是返回 401 Unauthorized
【发布时间】:2018-07-02 11:10:32
【问题描述】:

我正在开发一个带有 Rails API 的 Angular 应用程序。我正在使用Devise Token Auth6.x branch of angular-token。我可以毫无问题地 CRUD 用户,并且可以登录,但是当我尝试访问受限制的资源(通过 before_action :authenticate_user! 帮助程序限制的资源)时,无论我是否登录,我都会收到错误消息。

相关控制者

class QuestionsController < ApplicationController
    before_action :authenticate_user!

    # GET /questions.json
    def index
      @questions = Question.all

      # This code is never reached due to the :authenticate_user! helper, 
      # but when I comment it out, I get the following:
      puts user_signed_in?  # => false
      puts current_user     # => nil

      render json: @questions
    end

一些事情:

  • 我肯定按照angular-token 登录——TokenService.UserSignedIn()401 Unauthorized response 时返回true
  • 我已启用 CORS。
  • 我在 rack-cors 配置中公开了以下标头:['access-token', 'expiry', 'token-type', 'uid', 'client']

任何帮助将不胜感激。

登录响应示例

{
    "data": {
        "id": 1,
        "email": "me@example.com",
        "provider": "email",
        "uid": "me@example.com",
        "allow_password_change": false,
        "name": null,
        "nickname": null,
        "image": null
    }
}

角度代码

this.authService.loginUser({
  login: '',
  password: ''
})
.subscribe(resp => {
    if (resp.status === 200) {
      this.router.navigate(['/']);
    }
  },
  err => {
    // cut for brevity
});

编辑

我发现问题在于angular-token 没有设置身份验证标头,因为我认为这是以下代码中的错误:

// Add the headers if the request is going to the configured server
if (this.tokenService.currentAuthData && req.url.match(this.tokenService.apiPath)) {
  (<any>Object).assign(baseHeaders, {
    'access-token': this.tokenService.currentAuthData.accessToken,
    'client':       this.tokenService.currentAuthData.client,
    'expiry':       this.tokenService.currentAuthData.expiry,
    'token-type':   this.tokenService.currentAuthData.tokenType,
    'uid':          this.tokenService.currentAuthData.uid
  });
}

因为我没有定义apiPath,所以req.url.match(this.tokenService.apiPath)) 被评估为false,因此永远不会添加标题。

【问题讨论】:

  • 你能给我们看一个使用邮递员的例子吗?登录示例以查看 rails 服务器将返回什么。以及调用 API 时的 Angular 代码。
  • 我添加了示例。请注意,登录本身可以正常工作,它是对问题所在资源的请求。
  • 我需要查看您回复的标题。您的响应标头应包含下一个参数:访问令牌 - uid - 客户端 - 到期。应该存储此参数,然后将其添加到您发出的每个 http 请求中。你已经这样做了吗?
  • 是的,响应标头包括所有这些标头。令牌的存储是 angular-token 的用途。
  • 不,即使使用 angular-token,您也需要设置请求的标头,如果您没有设置,我认为这是错误的。

标签: ruby-on-rails angular ruby-on-rails-5 rails-api devise-token-auth


【解决方案1】:

我不知道 angular-token,但我的基于 React/Redux 的应用程序也遇到了同样的问题 - 事实证明,这确实只是标题丢失或未正确设置的问题。

由于某种原因,基于DeviseTokenAuth:: 的控制器似乎只能通过设置clientaccess-token 来工作,但是对于受DeviseTokenAuth::Concerns::SetUserByToken 保护的所有其他资源,您必须完全按照预期设置all 标头,并且由 devise_token_auth 记录。

  • 检查标题值和格式。
  • 检查标头是否与上一个请求(在您的情况下为身份验证请求)返回的标头完全相同。
  • 另外,检查您的映射

config/initializers/devise_token_auth.rb

config.headers_names = {:'access-token' => 'access-token',
                     :'client' => 'client',
                     :'expiry' => 'expiry',
                     :'uid' => 'id',
                     :'token-type' => 'token-type' }

(它定义了预期的 http 标头的名称(不是模型/活动记录属性)。

【讨论】:

    猜你喜欢
    • 2020-02-09
    • 2021-10-11
    • 2023-01-20
    • 1970-01-01
    • 2020-12-15
    • 2015-03-13
    • 2021-09-02
    • 2020-10-02
    • 2021-10-19
    相关资源
    最近更新 更多