我有一个用Ruby on Rails / oAuth编写的后端,它与Angular连接。创建用户或身份验证时,我得到以下errors
:
POST https://*=password 401 (Unauthorized)
{"error":"invalid_grant","error_description":"The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."}
ERROR Error: Uncaught (in promise): {"error":"invalid_grant","error_description":"The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."}
和
Failed to load https://*/api/users: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://*' is therefore not allowed access. The response had HTTP status code 500.
{
"isTrusted": true
}
当我登录时,进入数据库的数据被获取,但是错误仍然存在,并且您无法登录该帐户,请告诉我问题所在。
身份验证:
import { Injectable, Inject } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { Router } from '@angular/router';
import { Location } from '@angular/common';
import { Subject } from 'rxjs/Subject';
import { APP_CONFIG, AppConfig } from '../app.config';
import { NotificationsService } from 'angular2-notifications';
@Injectable()
export class AuthService {
public accessToken: string;
public isLoggedIn: Subject<boolean> = new Subject<boolean>();
private tokenUrl: string;
private baseUrl: string;
private headers = new Headers({'Content-Type': 'application/json'});
private _isLoggedIn: boolean;
constructor(
private http: Http,
private router: Router,
private location: Location,
private _flash: NotificationsService,
@Inject(APP_CONFIG) config: AppConfig
) {
this.baseUrl = config.serverUrl;
this.tokenUrl = `${config.serverUrl}/oauth/token?client_id=${config.clientId}&grant_type=password`;
}
login(user) {
let body = JSON.stringify(user);
return this.http.post(this.tokenUrl, body, {headers: this.headers})
.subscribe(res => {
if (res.status == 200) {
this.setAccessToken(res.json().access_token);
this.setLogIn(true);
this.router.navigate(['/admin']);
this._flash.success('', 'Signed in successfully!');
}
}, error => {
this.handleError(error.text(), 'Login failed!')
});
}
logout() {
this.removeAccessToken();
this.setLogIn(false);
this.router.navigate(['/login']);
this._flash.success('', 'Signed out successfully!');
}
registration(user) {
const url = `${this.baseUrl}/api/users`;
let body = JSON.stringify({user: user});
this.http.post(url, body, { headers: this.headers })
.subscribe(res => {
if (res.status == 200) {
this.router.navigate(['/login']);
this._flash.success(
'Registration successfully!',
'Please check your mailbox and confirm your email address'
);
}
}, error => {
this.handleError(error.text(), 'Registration failed!')
});
}
checkConfirmationToken(confirmation_token: string): Promise<Object> {
const url = `${this.baseUrl}/api/users/${confirmation_token}/confirm_email`;
return this.http.get(url)
.toPromise()
.then(res => res.json())
.catch(error => {
this.router.navigate(['/login']);
this.handleError(error, 'Could not confirm email address!');
});
}
private setAccessToken(token: string) {
localStorage.setItem('token', token);
}
private setLogIn(value: boolean) {
this._isLoggedIn = value;
this.isLoggedIn.next(this._isLoggedIn);
}
private removeAccessToken() {
localStorage.removeItem('token');
}
private handleError(error: any, flash: any = null): Promise<any> {
console.error(error);
flash ? this._flash.error('', flash) : null;
return Promise.reject(error.message || error);
}
}
也许我没有提供我所需的一切,请说出您还需要什么。
答案 0 :(得分:1)
问题不在于您的前端,而在于您的Rails
后端。由于前端和后端的“来源”不同,因此您需要允许来自不同来源的访问。
此blog post提供的代码段应为您指明正确的方向:
# Gemfile
gem 'rack-cors'
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:4200'
resource '*',
headers: :any,
methods: %i(get post put patch delete options head)
end
end
为进一步阅读,您可以看一下此detailed post。