Reputation: 338
I have a backend written in Ruby on Rails/oAuth it connects with Angular. When creating a user or authentication, I get these 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."}
And
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
}
When I log in, the data into the database gets, but still the error flies and you can not log into the account, tell me the problem.
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);
}
}
Maybe I did not give everything I needed, say what else you need.
Upvotes: 4
Views: 329
Reputation: 2633
The problem lies not within your frontend, but in your Rails
backend. Since the frontend and backend "live" in different origins, you need to allow access from different origins.
The code snippet provided at this blog post should point you in the right direction:
# 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
For further reading, you can take a look at this detailed post.
Upvotes: 1