Angular / Ruby on Rails / oAuth-提供的授权授予无效

时间:2018-07-09 13:08:16

标签: angular typescript angular5

我有一个用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);
  }
}

也许我没有提供我所需的一切,请说出您还需要什么。

1 个答案:

答案 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