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

问题描述 投票:3回答:1

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

也许我没有给出我需要的一切,说出你还需要什么。

angular typescript angular5
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.