Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 How to get token by sending credentials

I'm using Angular2 to get access token from a Java Spring back-end application. I can get the token via CURL but not via Angular form.

 curl localhost:8085/uaa/oauth/token --data "grant_type=password&scope=write&username=MY-USERNAME&password=MY-PASSWORD" --user user:pwd

I enabled Cors on Java back-end like this:

 public void doFilter(ServletRequest servletRequest, ServletResponse   servletResponse, FilterChain chain) throws IOException, ServletException {
    final HttpServletResponse response = (HttpServletResponse) servletResponse;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE, GET, HEAD, OPTIONS");
    response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, If-Modified-Since");
    chain.doFilter(servletRequest, servletResponse);
}

My Angular code looks like this:

import {Injectable, Component} from 'angular2/core';
import {Observable} from 'rxjs/Rx';
import {Http, HTTP_PROVIDERS, Headers} from 'angular2/http';

@Component({
   viewProviders: [HTTP_PROVIDERS]
})

@Injectable()
export class Authentication {
  token:string;
  http:Http;

  constructor(http:Http) {
    this.token = localStorage.getItem('token');
    this.http = http;
  }

  login(username:String, password:String) {

    var url = 'http://localhost:8085/uaa/oauth/token',
        body = JSON.stringify({
            username: username,
            password: password
        }),
        options = {
            headers: new Headers({
                'credentials': 'true',
                'grant_type': 'password',
                'scope': 'write',
                'Accept': 'application/json',
                'Content-Type': 'application/x-www-form-urlencoded'
            })
        };

      return this.http.post(url, body, options)
        .map((res:any) => {
            let data = res.json();
            this.token = data.token;
            localStorage.setItem('token', this.token);
        });
   }
}

The response from the server is:

Request URL:http://localhost:8085/uaa/oauth/token
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:[::1]:8085
like image 920
utnas Avatar asked Feb 16 '16 20:02

utnas


3 Answers

You might have two problems:

  1. The OPTIONS call is a preflight call. The CORS standard states that preflight calls should not include authentication. If your server isn't set up to handle that, you will get a 401 response. If you have control over the server you should be able to add something to allow the OPTIONS call through. With NGINX you can add something like:

    if ($request_method = 'OPTIONS') {return 200;}

    Not sure about you're particular server.

  2. Are you sure you are sending the credentials the right way? It looks like you are sending all this as individual headers rather than form-encoded data like you are with the curl request. This has worked for me:

    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    
    var credentials = "grant_type=authorization_code 
                    + "&credentials=true"
                    + "&scope=write" 
                    /* etc. */
    
    
    this.http.post('http://some.url', credentials, { headers: headers })
        .subscribe((res) => token = res.json())
    
like image 144
Mark Avatar answered Oct 27 '22 01:10

Mark


You should provide the username / password hints within the Authorization header with the "Basic" scheme. The value must encoded with base64 with the btoa function:

headers.append('Authorization', 'Basic ' + btoa('username:password');

Moreover, after having alook at your curling request, it seems that what you put in headers should be provided in the payload. This can be done using the UrlSearchParams class.

See rhis question for more details:

  • Angular2 Http post request not binding to ASP.NET 5 controller's action
like image 37
Thierry Templier Avatar answered Oct 27 '22 00:10

Thierry Templier


this is the following code for Nginx default.config which is working.

upstream book_up {
    server localhost:3002; 
}

server
{

    location /login {
        proxy_pass http://book_up/book/user/login;
    }
    location /health {
        proxy_pass http://book_up/book/health;
    }

    location /book {
        auth_request /auth;
        proxy_pass http://book_up$request_uri;
    }

    location = /auth {
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
        proxy_pass http://book_up/book/user/auth/;
        proxy_set_header Content-Length "";
        proxy_set_header   X-Original-URI $request_uri;
    }
}
like image 38
Varaprasad Reddy Avatar answered Oct 27 '22 01:10

Varaprasad Reddy