我有一个用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
}
当我登录时,数据进入数据库,但仍然出现错误,你无法登录帐户,告诉我问题。
auth.ts:
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);
}
}
也许我没有给出我需要的一切,说出你还需要什么。
问题不在于你的前端,而是在你的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。