如何使用 Angular 2 发送 OAuth2 的客户端 ID 和秘密 ID?

Posted

技术标签:

【中文标题】如何使用 Angular 2 发送 OAuth2 的客户端 ID 和秘密 ID?【英文标题】:How to send the client id and secret id of OAuth2 using Angular 2? 【发布时间】:2017-06-08 02:45:46 【问题描述】:

我使用带有资源服务器和授权服务器的 spring boot 开发了用于 OAuth2 的 Rest API。我可以使用 cURL、POSTMAN Rest 客户端成功获取令牌,并且可以使用 OAuth 提供的令牌请求授予的服务。现在,我需要知道如何使用 angular2 传递 OAuth2 client_id、secret_id。 我将请求传递为 getOAuthToken(clientCredintial):Observable

var body = `username=admin&password=nex1234`;
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let response = this.http.post(`$AppSettings.BACK_ENDPOINT/oauth/token`,body, headers: headers );
let oauthTokenItems = response.map(mapOAuthTokenItems);
return oauthTokenItems;

但我在浏览器上遇到异常 选项http://localhost:8080/rwsweb/oauth/token 401 ()

oauth-token:1 XMLHttpRequest cannot load                 http://localhost:8080/rwcweb/oauth/token. Response for preflight has invalid     HTTP status code 401
error_handler.js:47 EXCEPTION: Response with status: 0  for URL: null
ErrorHandler.handleError @ error_handler.js:47
next @ application_ref.js:272
schedulerFn @ async.js:82

Subscriber.js:227 未捕获响应 _body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers...enter code here

【问题讨论】:

【参考方案1】:

使用代码:

import  Injectable  from '@angular/core'
import  Http  from '@angular/http';
import  Headers, RequestOptions  from '@angular/http';

@Injectable()
export class LoginService 
    private urlLogin: string;

    constructor(private http: Http) 
        this.urlLogin = "http://yourserver/oauth/token";
    

    public login(user) 

        let headers = new Headers(
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
            "Authorization": "Basic " + btoa("yourclientid" + ':' + "yourclientsecret")
        );

        let options = new RequestOptions( headers: headers );

        let data = "username=" + user.yourlogin + "&password=" + encodeURIComponent(user.yourpass) + "&grant_type=password&" +
            "client_secret=yourclientsecret&client_id=yourclientid";

        return this.http.post(this.urlLogin, data, options)
            .map(res => res.json());
    


【讨论】:

我在上面尝试过,但现在我在 Chrome brawser 上遇到了一个异常,因为 XMLHttpRequest 无法加载 localhost:8080/rwcweb/oauth/token。预检响应包含无效的 HTTP 状态代码 401 是的,我在 Postman 中测试过。在那个工作正常。这个异常“preflight has invalid HTTP status code 401”不是在 Safari 浏览器上出现,而是在 Chrome 上出现。因为如果我们将请求作为带有所有凭据的 POST 传递,那么 Chrome 会将其转换为 OPTIONS 方法。我不明白如何在 Chrome 浏览器上传递此请求【参考方案2】:

使用纯javascript in this post 解决了这个问题。对于角度 5,我能够使用以下代码获得 200 响应状态:

getAccessToken(username: string, password: string): Observable<AuthToken> 

   let oauth2_token_endpoint = '<your_token_endpoint>';
   let oauth2_client_id = '<your_client_id>';
   let oauth2_client_secret = '<your_client_secret>';

    const httpOptions = 
        headers: new HttpHeaders(
            'Content-Type': 'application/x-www-form-urlencoded',
            // 'Authorization': 'Basic ' + btoa(oauth2_client_id + ':' + oauth2_client_secret)
        )
    ;


    const body = 'client_id=0&client_secret=1&grant_type=password&username=2&password=3'
        .replace('0', oauth2_client_id)
        .replace('1', oauth2_client_secret)
        .replace('2', username)
        .replace('3', password);

    // console.log(body);

    return this.http.post<AuthToken>(oauth2_token_endpoint, body, httpOptions);

AuthToken 接口:

export interface AuthToken 
    access_token: string,
    token_type: string,
    expires_in: number,
    refresh_token: string,
    scope: Array<string>

您的登录功能如下所示:

login(username: any, password: any): void 

    this.getAccessToken(username, password).subscribe(
        response => 
            // ...any login logic- cookies and all the good stuff goes here
            this.isLoggedIn = true; 
            console.log(response);
        ,
        error => 
            this.isLoggedIn = false;
            console.log(error);
        );

【讨论】:

以上是关于如何使用 Angular 2 发送 OAuth2 的客户端 ID 和秘密 ID?的主要内容,如果未能解决你的问题,请参考以下文章

带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]

将 OAuth2 访问令牌配置为 typescript-angular2 客户端

Angular 5 + OAuth2:未使用库设置令牌 [angular-oauth2-oidc]

如何使用 Spring Boot + Angular 处理外部 OAuth2 身份验证

如何使用 typescript/angular 正确构建 OAuth2 GET 请求?

如何使用 Angular -> Spring Boot Oauth2 -> Keycloak 获取 keycloak 令牌