Angular 6 - Add JWT bearer token to header not working - jwt

I'm trying to add the auth bearer token header while getting a comment from the asp.net core 2.2 backend in angular 6
getComment(postId: number): Observable<IComment[]>{
let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json');
let authToken = localStorage.getItem('auth_token');
headers.append('Authorization', 'Bearer ' + authToken);
console.log(authToken);
return this.httpClient.get<IComment[]>('api/comment/post/' + postId, { headers });
}
This piece of code is not working. I am getting a value from console.log(authToken). When I copy the token in Postman, everything is working fine.
My login function in a service. This is working fine to, i'm getting the token from the backend.
login(login: ILogin) {
console.log(login);
return this.http
.post('api/auth/login', login)
.pipe(map((res: any) => {
localStorage.setItem('auth_token', res.auth_token);
this.loggedIn = true;
this._authNavStatusSource.next(true);
return true;
}));
}
When I remove authorization from the action in the backend, getting the comments is working fine. As you can see in the image below, the jwt token is just not being add to the header.
Postman:
Header information from chrome

You are not passing the headers in { headers } section.
Change return this.httpClient.get<IComment[]>('api/comment/post/' + postId, { headers }); to return this.httpClient.get<IComment[]>('api/comment/post/' + postId, { headers: headers });

When you say it's working fine via Postman, and that this is not a CORS issue (i.e., either CORS is enabled, or your JS is being served from the same origin as you API), I assume you're already subscribing to the returned Observable<IComment[]>.
The code above won't issue the request until there is a call somewhere that looks like this:
yourService.getComment(postId).subscribe(comments => { ... });
That will begin consuming the Observable and trigger the underlying HTTP request.

Related

CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to fetch an image resource that's part of a conversation message.
I've tried both FETCH as well as using AXIOS but I'm getting the same error message.
Here's an example of my FETCH request
const token = `${accountSid}:${authToken}`;
const encodedToken = Buffer.from(token).toString('base64');
let response = await fetch('https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
{
method:'GET',
headers: {
'Authorization': `Basic ${encodedToken}`,
}
});
let data = await response.json();
console.log(data);
And here's what Axios looked like
let config = {
method: 'get',
crossdomain: true,
url: 'https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
headers: {
'Authorization': `Basic ${encodedToken}`,
},
};
try {
const media = await axios(config);
console.dir(media);
} catch(err) {
console.error(err);
}
Both ways are NOT working.
After looking into it more, I found out that Chrome makes a pre-flight request and as part of that requests the allowed headers from the server.
The response that came back was this
as you can see, in the "Response Headers" I don't see the Access-Control-Allow-Headers which should have been set to Authorization
What am I missing here?
I have made sure that my id/password as well as the URL i'm using are fine. In fact, I've ran this request through POSTMAN on my local machine and that returned the results just fine. The issue is ONLY happening when I do it in my code and run it in the browser.
I figured it out.
I don't have to make an http call to get the URL. It can be retrieved by simply
media.getContentTemporaryUrl();

Flask JWT Extended- Different locations for access_token (header) & refresh_token(httpOnly cookie)

How to configure flask app with flask-jwt-extended for which we need something like below.
AccessToken/Bearer must sent as a Header (and not cookie)
RefreshToken must sent as httpOnlyCookie for /api/refreshtoken path only
How to set two different token one in header and one in cookie? We are able to set either both as cookie or both as a header.
Any help?
Thanks
Raxit
I wanted to do the same while building a React + Flask single page application after days of headache trying to understand authorization and authentication as I am a beginner.
Anyways, I managed to do it this way:
In Flask, config:
app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']
app.config['JWT_REFRESH_COOKIE_PATH'] = '/auth/refresh'
And what I return in my login function:
resp = jsonify({'access_token': access_token})
set_refresh_cookies(resp, refresh_token)
return resp, 200
And in my refresh function:
# Refresh access token
#app.route('/auth/refresh', methods=['POST'])
#jwt_refresh_token_required
def refresh():
user = get_jwt_identity()
resp = {
'access_token': create_access_token(
identity={
'username': user['username'],
'role': user['role']
},
expires_delta=timedelta(seconds=600),
user_claims=user['role']
)
}
return jsonify(resp), 200
And on the front side, I collect the JSON access_token and set it in memory and use withCredentials to send the refresh_token with my API calls.
axios.defaults.withCredentials = true;
axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
more precisely:
.then(({ data: { access_token } }) => {
axiosHttp.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
return jwt_decode(access_token);
})
then I use the data from my decoded access_token in a React Context Component to authenticate access to pages depending on roles.
logout is simply setting to null my context and calling the api to unset the refresh cookie
#app.route('/auth/logout', methods=['DELETE'])
#jwt_required
def logout():
resp = jsonify({"msg": "Successfully logged out"})
unset_jwt_cookies(resp)
return resp, 200
it's quite simple in the end but it took me quite a while to figure out!

Unable to POST using Angular 7 : Header Does not work

I'm currently building out an Angular 7 App, and trying to implement the following HTTP API Call Scenario:
Request for an Application Token:
https://(URL)/token
Request Type: POST
Headers:
Accept: application/json
Request Body: empty
I have a Service class in the Angular app and the code is as follows:
import { HttpClient } from '#angular/common/http';
import { HttpHeaders } from '#angular/common/http';
The requestToken function is implemented as follows:
requestToken() {
let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/json');
return this.http.post(this.configUrl + '/token', headers);
}
The Service is then called in one of the components in the App:-
getToken() {
this.service.requestToken().subscribe( res => {
console.log(res);
}, error => {
console.log(error);
});
}
When I run the App, I get a 404 Not Found error in the console. I used Postman to make an API call, setting the 'Accept' header to 'application/json' and then specifying url as https://(URL)/token and I successfully get a response. But I'm unable to make it work via Angular.
Is there something else I need to do to set the header properly in Angular? Also, I have no way to check if CORS has been enabled on the API server as this is a third-party service which I'm trying to call.
Any help would be appreciated. Thanks
Solved the problem. Changed the POST call to the following:
requestToken() {
const httpHeaders = new HttpHeaders({
'Accept': 'application/json'
});
return this.http.post(this.configUrl + '/token', { body: ''}, { headers: httpHeaders });
}
Had to add an empty 'body' parameter

Setting authorization header in http client in ionic and angular 5

I am learning ionic for mobile development latest version. I used http client for calling REST API. But I am facing some issues -
1) I am using POST but it showing me as option.
2) How to set authorization header . I am using bearer token and my rest API is written in PHP.
Use HttpHeaders to set your token. token can be defined in a string
func() {
var headers = new HttpHeaders();
let body = new HttpParams();
body = body.set('key','value');
headers = headers.set("Authorization", "Bearer " + token)
return this.http.post('post-url.com', body,{
headers:headers
});
}
Hope that helps!

How to get Authenticated with spring security rest plugin in Grails

I'm using Grails version 2.4.3 . I am creating an application that supports RESTful APIs. Since access to these APIs should be authenticated , I tried out the Spring Security REST plugin. I checked out this example and what I could understand is , the /api/login controller is the authentication point which receives the user credentials in JSON format and after successful authentication it provides the acces token as response. I tried sending a POST request to /api/login/ with valid JSON data using the POSTMAN Rest Client. But it gives me the following error.
401 Unauthorized , Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
I also tried using IntellijIDEA's REST Client but doesn't work.
Then i tried by sending AJAX Request to /api/login/ with valid JSON data
, but getting 401 on console. What is the problem here? Is this the correct login end point? How can i get authenticated using JQuery?
Try this
$.ajax({
url: " http://localhost:8080/AppName/api/login",
type: "POST",
crossDomain: true,
data: JSON.stringify({"username":"yourusername" , "password":"yourpassword"}),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (response) {
console.log(response);
},
error: function (xhr, status) {
alert("error");
}
}) });
You can try this code for authentication,I am sending user id and password in request header you can try as you wish :-
inject following services:-
def springSecurityService
def authenticationManager
and use following code
def login = {
final String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.startsWith("Basic")) {
boolean authResult = authenticateUser(authorization)
if (authResult) {
render response.status
} else {
render authFailed(response)
}
} else {
render authFailed(response)
}
}
protected boolean authenticateUser(String authorization) {
// Authorization: Basic base64credentials
def base64Credentials = authorization.substring("Basic".length()).trim();
byte[] credentials = base64Credentials.decodeBase64()
String actualCredential = new String(credentials)
// credentials format like username:password
final String[] values = actualCredential.split(":", 2);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(values[0], values[1]);
try {
def authentication = authenticationManager.authenticate(authRequest);
def securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
def session = request.session;
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}
catch (BadCredentialsException exception) {
return false
}
return true
}
protected HttpServletResponse authFailedResponse(HttpServletResponse response) {
response.setStatus(401)
response.setHeader("WWW-Authenticate", "Basic realm=\"nmrs_m7VKmomQ2YM3:\"")
return response;
}