ionic 3 header not sending Authorizaqtion 'bearer "token"' to server - ionic-framework

Im doing a login screen that takes a username and password.
if the login was successful the server will return a token.
then im trying to call another function to get user info but the authorization header is not being passed.
im trying my server method on postman and its working fine so i believe the problem is in the headers. May someone please advise me on what should be done?
let url = urlConst.Login;
let params1 = new HttpParams();
let loader = this.loadingcontroller.create({
content: stringEngConst.signinngin
});
let attributes = {
username: this.uname.value.toLowerCase(),
password: this.password.value,
grant_type: "password"
};
var headers = new HttpHeaders();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let body = 'username=' + this.uname.value.toLowerCase() + '&password=' + this.password.value + '&grant_type=password';
let data: Observable < any > = this.http.post(url, body, {
headers: headers
});
loader.present().then(() => {
data.subscribe(result => {
if (result.access_token != null) {
this.signintoken = result.access_token;
this.storage.set(storageConst.SIGN_IN_TOKEN, result.token_type + " " + result.access_token);
headers.append('Authorization', 'Bearer ' + this.signintoken);
let url1 = 'http://localhost:57940/API/Account/GetUserInfo/';
let info: Observable < any > = this.http.get(url1, {
headers: headers
});
info.subscribe(result => {
/*Do Something*/
});
}
Please Note that result.access_token != null is true. and i am successfully getting the token back. But it is not being passed again to the second url (info)

Looks like this SO post may solve things for you: https://stackoverflow.com/a/47805759/6599076
You may want to use:
headers = headers.append('Authorization', 'Bearer ' + this.signintoken);

You are using the same headers as for the first http request:
var headers = new HttpHeaders();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
Depending on your end point for the subsequent call it might be that you need to set headers differently:
Try creating new headers with
var headers2 = new HttpHeaders();
headers.append('Content-Type', 'application/json');
Or get rid of Content-Type completely depending on what your end point expects.
Also if you are using Ionic 3 its worth to check which Http module you are using (HttpClient or the older one) as there are some differences in how these tend to handle request options.

Related

Flutter qraphQl issue with setting requesting data from body of api

I am trying to connect to an graphQl api that uses the token as the password in the Basic auth section of the header. I have tried using flutter_graphql but as I only get the token back after the user logs in. I have managed to get logged in using:
String username = "";
String password = token;
String basicAuth = 'Basic' + base64Encode(utf8.encode("$username:$password"));
String projects = "query Projects{Projects{id name}}";
Uri newUri = Uri.parse("$link");
var newResponse = await http.post(newUri, headers: {
"Authorization": basicAuth,
"Content-Type": "application/graphql"
}, body: //I need to get projects here.
);
var newNonJsonData = newResponse.body;
group("Testing the graph ql data after logging in: ", () {
test("Logged in", () {
expect(newResponse.statusCode, 200);
});
test("getting the data from the api", () {
print("non json return:" + newNonJsonData);
});
});
I have tried to set the body as
jsonEncode({
'query' : prjects
})
but the moment I request the data it asks to log in.
Please could someone help!!!

Post to given endpoint as multipart file

I've got working backend in Spring Boot with JWT-secured endpoint for modifying avatar of current user. The following request from Insomnia with correct Bearer works fine:
But this code
updateAvatar(context, avatar) {
const fd = new FormData();
fd.append('file', avatar.data);
return new Promise((resolve, reject) => {
axios.post('/saveavatar',
{file: fd},
{headers: {'Authorization': 'Bearer ' + localStorage.getItem('access_token')}})
.then(response => {
resolve(response)
})
.catch(error => {
reject(error)
})
})
},
fails with error
the request was rejected because no multipart boundary was found
What am I doing wrong?
The second argument to post should be the actual FormData, fd in your case.
axios.post('/saveavatar',
fd,
{headers: {'Authorization': 'Bearer ' + localStorage.getItem('access_token')}})
The reason it works in Insomia is that it takes care of your request and figures out that it needs to ads a boundary, axios will do the same, but needs a valid FormData.

Angular 6 - Add JWT bearer token to header not working

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.

ionic 3 - HttpClient response shows inn clear text or how to disable httpclient cache

This is for my understanding I am asking this question.
My client is telling, they are able to see service response in cache folder if the device is rooted/jailbreak. I am using HTTPS.
import { HttpClient, HttpHeaders, HttpEventType, HttpEvent } from '#angular/common/http';
APIBASEURL = "https://........"
//MARK:- HTTP GET method
getServiceData(path: string) {
var APIFULLURL = this.APIBASEURL + path;
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json; charset=utf-8');
headers = headers.set("Content-Encoding", 'gzip')
headers = headers.set('Accept', 'application/json;charset=utf-8')
headers = headers.set('Authorization', this.APIHeaderKey);
headers = headers.set('Cache-control', 'no-cache');
headers = headers.set('Cache-control', 'no-store');
headers = headers.set('Expires', '0');
headers = headers.set('Pragma', 'no-cache');
//*****************Service Log ********************//
console.log("==URL ===" + APIFULLURL);
//*****************Service Log ********************//
const req = new HttpRequest('GET', APIFULLURL,{
headers: headers,
reportProgress: true,
withCredentials : true
});
return this.http.request(req).timeout(50000)
}
//MARK:- HTTP POST method
postService(path: string, isLogin: boolean, serviceBody: any) {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json; charset=utf-8');
headers = headers.set("Content-Encoding", 'gzip')
headers = headers.set('Accept', 'application/json')
headers = headers.set('Authorization', this.APIHeaderKey)
headers = headers.set('Cache-control', 'no-cache');
headers = headers.set('Cache-control', 'no-store');
headers = headers.set('Expires', '0');
headers = headers.set('Pragma', 'no-cache');
var APIFULLURL = this.APIBASEURL + path;
//*****************Service Log ********************//
console.log("==URL ===" + APIFULLURL);
//*****************Service Log ********************//
try {
return this.http.post(APIFULLURL, JSON.stringify(serviceBody), { headers: headers, withCredentials : true} ).timeout(50000);
} catch (error) {
console.log(error);
alert("Error" + error)
}
}
when I call api service, httpclient is saving the response in the cache. I do not manually save in the cache or local storage.
problem is first to install and access the app, later jailbreak/ rooted, go directly to cache folder and see the service response clear text.
How can I encrypt this cache value? according to my knowledge, before the process, HttpClient save in the cache.
Please guide me how to encrypt the service response in the cache.
This is the high severity issue in my app.
How can I disable 'HttpClient to keep it in the cache?

http post - how to send Authorization header?

How do you add headers to your http request in Angular2 RC6?
I got following code:
login(login: String, password: String): Observable<boolean> {
console.log(login);
console.log(password);
this.cookieService.removeAll();
let headers = new Headers();
headers.append("Authorization","Basic YW5ndWxhci13YXJlaG91c2Utc2VydmljZXM6MTIzNDU2");
this.http.post(AUTHENTICATION_ENDPOINT + "?grant_type=password&scope=trust&username=" + login + "&password=" + password, null, {headers: headers}).subscribe(response => {
console.log(response);
});
//some return
}
The problem is, that angular doesn't add Authorization header. Instead of that, in request I can see following additional headers:
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
and sdch added in Accept-Encoding:
Accept-Encoding:gzip, deflate, sdch
Unfornately there is no Authorization header. How should I add it correctly?
Whole request sent by my code looks as follow:
OPTIONS /oauth/token?grant_type=password&scope=trust&username=asdf&password=asdf HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:3002
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Referer: http://localhost:3002/login
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,pl;q=0.6
Ok. I found problem.
It was not on the Angular side. To be honest, there were no problem at all.
Reason why I was unable to perform my request succesfuly was that my server app was not properly handling OPTIONS request.
Why OPTIONS, not POST? My server app is on different host, then frontend. Because of CORS my browser was converting POST to OPTION:
http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
With help of this answer:
Standalone Spring OAuth2 JWT Authorization Server + CORS
I implemented proper filter on my server-side app.
Thanks to #Supamiu - the person which fingered me that I am not sending POST at all.
you need RequestOptions
let headers = new Headers({'Content-Type': 'application/json'});
headers.append('Authorization','Bearer ')
let options = new RequestOptions({headers: headers});
return this.http.post(APIname,body,options)
.map(this.extractData)
.catch(this.handleError);
for more check this link
I believe you need to map the result before you subscribe to it. You configure it like this:
updateProfileInformation(user: User) {
var headers = new Headers();
headers.append('Content-Type', this.constants.jsonContentType);
var t = localStorage.getItem("accessToken");
headers.append("Authorization", "Bearer " + t;
var body = JSON.stringify(user);
return this.http.post(this.constants.userUrl + "UpdateUser", body, { headers: headers })
.map((response: Response) => {
var result = response.json();
return result;
})
.catch(this.handleError)
.subscribe(
status => this.statusMessage = status,
error => this.errorMessage = error,
() => this.completeUpdateUser()
);
}
If you are like me, and starring at your angular/ionic typescript, which looks like..
getPdf(endpoint: string): Observable<Blob> {
let url = this.url + '/' + endpoint;
let token = this.msal.accessToken;
console.log(token);
return this.http.post<Blob>(url, {
headers: new HttpHeaders(
{
'Access-Control-Allow-Origin': 'https://localhost:5100',
'Access-Control-Allow-Methods': 'POST',
'Content-Type': 'application/pdf',
'Authorization': 'Bearer ' + token,
'Accept': '*/*',
}),
//responseType: ResponseContentType.Blob,
});
}
And while you are setting options but can't seem to figure why they aren't anywhere..
Well.. if you were like me and started this post from a copy/paste of a get, then...
Change to:
getPdf(endpoint: string): Observable<Blob> {
let url = this.url + '/' + endpoint;
let token = this.msal.accessToken;
console.log(token);
return this.http.post<Blob>(url, null, { // <----- notice the null *****
headers: new HttpHeaders(
{
'Authorization': 'Bearer ' + token,
'Accept': '*/*',
}),
//responseType: ResponseContentType.Blob,
});
}
I had the same issue. This is my solution using angular documentation and firebase Token:
getService() {
const accessToken=this.afAuth.auth.currentUser.getToken().then(res=>{
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': res
})
};
return this.http.get('Url',httpOptions)
.subscribe(res => console.log(res));
}); }}
Here is the detailed answer to the question:
Pass data into the HTTP header from the Angular side (Please note I am
using Angular4.0+ in the application).
There is more than one way we can pass data into the headers.
The syntax is different but all means the same.
// Option 1
const httpOptions = {
headers: new HttpHeaders({
'Authorization': 'my-auth-token',
'ID': emp.UserID,
})
};
// Option 2
let httpHeaders = new HttpHeaders();
httpHeaders = httpHeaders.append('Authorization', 'my-auth-token');
httpHeaders = httpHeaders.append('ID', '001');
httpHeaders.set('Content-Type', 'application/json');
let options = {headers:httpHeaders};
// Option 1
return this.http.post(this.url + 'testMethod', body,httpOptions)
// Option 2
return this.http.post(this.url + 'testMethod', body,options)
In the call you can find the field passed as a header as shown in the image below :
Still, if you are facing the issues like.. (You may need to change the backend/WebAPI side)
Response to preflight request doesn't pass access control check: No
''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:4200'' is therefore not allowed
access
Response for preflight does not have HTTP ok status.
Find my detailed answer at https://stackoverflow.com/a/52620468/3454221
if you are a ruby on rails developer and you facing a similar issue, this is because of the config of your backend: especially in api mode
so with
gem 'rack-cors' installed
goto app/config/cors.rb
Be sure to restart your server when you modify this file.
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'domain_name:port or just use *'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true
end
end
the *credentials:true line does the trick
then in your SessionController
after a user is valid for login
insert a line(this assumes you are using gem 'jwt')
token = user.generate_jwt
response.headers['Authorization'] = token
generate_jwt is a method called in model User , it is
JWT.encode(id, key, alogrithm)
If you use django, that is already taken care for you
you just have to use
installed app: restframework_simplejwt