Angular 2和Token身份验证

时间:2017-08-13 18:35:27

标签: angular rest

我在Java中有一个简单的REST API。我通过Postman测试这个api,一切正常。但现在我想用这个API学习Angular2。我尝试登录到应用程序,我有问题,因为我不知道如何在Angular2中构建请求。在邮递员中,我这样做。

Postman screen shot 这是我的代码后端配置。

package org.mroczek.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{

    @Autowired
    private AuthenticationManager authenticationManager;


    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient("my-trusted-client")
                .authorizedGrantTypes("client_credentials", "password")
                .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT").scopes("read","write","trust")
                .resourceIds("oauth2-resource").accessTokenValiditySeconds(5000).secret("secret");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

}

这是我的autentication.service.ts

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import 'rxjs/add/operator/map'
import {map} from 'rxjs/operator/map';

@Injectable()
export class AuthenticationService {
    constructor(private http: Http) { }

    login(username: string, password: string) {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json;charset=UTF-8');
        let body = JSON.stringify({ username: username, password: password });

        return this.http.post('http://localhost:8080/',JSON.stringify({username, password }),{headers})
            .map((response: Response) => {
            console.log(response)
                // login successful if there's a jwt token in the response
                let user = response.json();
                if (user && user.token) {
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                }
                console.log(user);
                return user;
            });
    }

    logout() {
        // remove user from local storage to log user out
        localStorage.removeItem('currentUser');
    }
}

当我发送请求时,在后端日志中我看到找不到该页面。但我不知道什么是正确的URL。

2 个答案:

答案 0 :(得分:0)

如果您只是想了解它是如何完成的,那么请查看Angular's Http documentation。 示例用法可能看起来像这样(未经测试,我根本不使用此api):

@Injectable()
export class SomeService {
  constructor(protected http: Http) {}

  public login() {
    let headers = new Headers();
    headers.append('Access-Control-Allow-Origin', '*');
    headers.append('Access-Control-Allow-Methods', 'POST');
    headers.append('Access-Control-Allow-Credentials', 'true');
    headers.append('Accept', 'application/json');
    headers.append('Content-type', 'application/json');
    let body = {}; // request's body here... (in general password shouldn't be passed as a query parameter, so you will probably like to place it here 
    return http.post('http://localhost:8080/oath/token?grant_type=password&username=user', JSON.stringify(body), {headers});
  }
}

希望它有效......祝你好运管理数百个端点的代码......

如果您想为您的应用程序提供一个好的解决方案,那么我会推荐一个像这样的库 ng2-http。它成功地抽象了整个Http层 - 到目前为止我的项目中没有使用过单一的解决方法。使用它时,您不需要手动创建每个请求,每次解析响应等... 用法示例:适用于v0.0.3

// ./providers/rest/localhost.api.ts
@Injectable()
@BaseUrl('http://localhost:8080')
@DefaultHeaders({
  'Accept': 'application/json',
  'Content-Type': 'application/json'
})
export class LocalhostApi extends RESTClient {
  @POST('oath/token')
  public postOathToken(
      @Query('grant_type') grantType: string,
      @Query('username') userName: string,
      @Query('password') password: string
      @Body body: PostOathTokenBody
  ) {
    return undefined;
  }
}

// ./providers/rest/types.ts
// for this example let's say you want to send the exact same data as you received
export interface PostOathTokenBody {
  access_token: string;
  token_type: string;
  expires_in: number;
  scope: string;
}

// ./services/some.service.ts
@Injectable()
export class SomeService {
  constructor(protected localhostApi: LocalhostApi) {}

  public login(body: PostOathTokenBody) {
    // and that's it, every time you want to use the endpoint, just do:
    return this.localHostApi.postOathToken('username', 'user', 'password', {});
  }
}

此外,我还定义了其他Apis将扩展的其他AbstractApi类,并添加:responseInterceptor(res) { return res.map(r => r.json()); },这样您就可以在每个请求中获得解析数据。

答案 1 :(得分:0)

所以我使用Vue.JS和axios

来使用我的API
login(){
            var params = new URLSearchParams();
            params.append('grant_type', 'password');
            params.append('username', this.username);
            params.append('password',this.password);
            axios({
                method:'post',
                url:'oauth/token',
                auth:{username:'my-trusted-client',password:'secret'},
                headers: {"Content-type": "application/x-www-form-urlencoded; charset=utf-8"},
                data:params
            }).then(function(response){
                set_cookie("access_token",response.data.access_token);
                document.location.replace("/");
            });
        }

以上是代码,此代码正常运行。但我仍然认为如何在Angular 2中正确地做到这一点。

在Angular 2中,我尝试这样做。

  login(username, password): Observable<Response> {
const headers = new Headers({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'});
headers.append('Authorization', 'Basic bXktdHJ1c3RlZC1jbGllbnQ6c2VjcmV0');
headers.append('grant_type', 'password');
const options = new RequestOptions({headers: headers});
const body = JSON.stringify({username: username, password: password});

return this.http.post('http://localhost:8080/oauth/token', body, options)
  .catch(this.handleError);
}

但我有这个错误。

XMLHttpRequest cannot load http://localhost:8080/oauth/token. Response for preflight has invalid HTTP status code 401