Ruby on rails rails 4 API在使用angular2令牌包成功登录后给出401未经筛选的响应
我有一个设置,其中我有一个rails 4 API,具有gem designe_token_auth,并作为一个单独的应用程序托管,因此我还配置了机架COR来处理跨源请求。在我的前端angular2应用程序上使用angular2令牌,我已经能够通过API成功注册、登录以及注销用户。 然而,我遇到的问题只有在用户登录并且刷新浏览器时才会发生,我在rails API控制台以及在firefox和chrome中签入的浏览器中都会看到这个错误Ruby on rails rails 4 API在使用angular2令牌包成功登录后给出401未经筛选的响应,ruby-on-rails,angular,ruby-on-rails-4,rails-api,Ruby On Rails,Angular,Ruby On Rails 4,Rails Api,我有一个设置,其中我有一个rails 4 API,具有gem designe_token_auth,并作为一个单独的应用程序托管,因此我还配置了机架COR来处理跨源请求。在我的前端angular2应用程序上使用angular2令牌,我已经能够通过API成功注册、登录以及注销用户。 然而,我遇到的问题只有在用户登录并且刷新浏览器时才会发生,我在rails API控制台以及在firefox和chrome中签入的浏览器中都会看到这个错误 Started GET "/api/v1/auth/valida
Started GET "/api/v1/auth/validate_token" for 127.0.0.1 at 2017-02-06 17:42:49 +0500
Processing by DeviseTokenAuth::TokenValidationsController#validate_token as JSON
接
SELECT "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1 [["uid", "abc@xyz.com"]]
Completed 401 Unauthorized in 76ms (Views: 0.2ms | ActiveRecord: 0.3ms)
在我的Angular2应用程序中配置这个包的过程中,我最初的假设是它将在每个请求中隐式地包含身份验证头。然而,在反复阅读gem的文档之后,当我在app.component.ts文件中初始化令牌服务时,我自己也添加了标题
this._tokenService.init({
apiPath: API_PATH,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"access_token_name": localStorage.getItem('accessToken'),
"client_name": localStorage.getItem('client'),
"uid_name": localStorage.getItem('uid')
}
}
});
即使在这之后,响应仍然没有更改为请求,我也无法在服务器端接收这些头
然而,经过数小时的检查,我终于想到了一个主意,那就是检查我在服务器上得到的头,当我在服务器端应用程序上使用ruby的request.header.inspect时,我得到了以下输出,其中包含验证令牌所需的信息,但这些头值的键的名称似乎是与designe_-token_-auth希望验证令牌的方式不同(我查看了designe_-auth_-token gem的来源)
我相信用户不是由Desive_token_auth gem根据传递的头设置的
在反复阅读Angular2 token以及Desive_token_auth gem的文档之后,我对是否手动添加用于身份验证的头文件感到困惑,因为我认为它们已经被传递了,但使用了不同的密钥。
我只想知道我是否经历了这种情况——几乎一整天了,我想不出一个办法来确定401计划的反应背后的原因
非常感谢
编辑:
此外,在服务器端成功登录后,访问当前_用户或任何Desive helper时,我也将获得零
下面是我的api rails应用程序的机架cors配置。
应用程序.rb
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/cors',
:headers => :any,
:methods => [:post],
:credentials => true,
:max_age => 0
resource '*',
:headers => :any,
:expose => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
:methods => [:get, :post, :options, :delete, :put]
end
end
我检查时得到的标题如下:
{"success":false,"errors":["Invalid login credentials"]}
当我尝试使用以下代码手动检查令牌的验证时
this._tokenService.validateToken().subscribe(
res => console.log(res),
error => console.log(error)
);
您还应该在请求Desive_Token_auth进行身份验证时传递
到期
和令牌类型
,如下所示:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Uid', this.uid);
headers.append('Client', this.client);
headers.append('Access-Token', this.access_token);
headers.append('Expiry', this.expiry);
headers.append('Token-Type', 'Bearer');
this.http.post('http://my-api.com/', JSON.stringify(resource), {headers: header}).subscribe((res)=>{
#Your Logic Here
});
此示例适用于一般HTTP请求,但您可以在angular token插件上应用该规则。例如:
this._tokenService.init({
apiPath: API_PATH,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"access_token_name": localStorage.getItem('accessToken'),
"client_name": localStorage.getItem('client'),
"uid_name": localStorage.getItem('uid'),
"expiry_name": localStorage.getItem('expiry'),
"token-type_name': 'Bearer'
}
}
});
您已经为
designe\u-token\u-auth
设置了自定义标题名称?第一个示例使用默认配置,标题名称末尾没有\u-name
,如果是这种情况,您应该尝试修改。在此问题上花了几天时间,并在re上反复发布了多个相关问题的线程我遇到了这个问题,我意识到我有rails 4,并使用rails api gem生成了我的api。
之后,我创建了一个带有--API选项的rails 5 API(不带rails API gem)通过api端的设计令牌\u验证和机架cors,我成功地使用angular2令牌包发送授权请求。同时,我还能够发送授权http post请求,其中授权头包括访问令牌、令牌类型、到期日、uid,如de中所述vise_token_auth gem的文档
这可能不是确切的解决方案,或者我可能没有找到问题的原因,但这对我来说是有效的。非常感谢您的回复!我会尝试正确的方法!事实上,我之前也尝试过这些更改,但没有运气。即使我在全局选项中没有传递任何标题,但在检查服务器端的标题时也是如此我得到的是这些值,但正如我在问题中提到的,这些值使用的是不同的键。这与我的服务器端上的机架ors配置或其他任何内容有关吗?此外,在成功登录服务器端后访问当前用户或任何Desive helper时,我也得到了零。您是否在CORS配置中公开了头文件?请参阅t是的,先生,我有。我的问题中也添加了机架cors的配置。我访问了多个在线资源,然后添加了我在问题中提到的配置。从我看到的情况来看,您应该重命名默认angular2令牌头以匹配cors配置中的头,或者重命名这些头和要添加的字段evise_token_auth在初始值设定项上使用类似于
designetokenauth.headers_name[:'access-token']=“HTTP_access_token”
this._tokenService.init({
apiPath: API_PATH,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"access_token_name": localStorage.getItem('accessToken'),
"client_name": localStorage.getItem('client'),
"uid_name": localStorage.getItem('uid'),
"expiry_name": localStorage.getItem('expiry'),
"token-type_name': 'Bearer'
}
}
});