I'm using MSAL lib for authorize my SPA.
Init:
msUserAgent = new Msal.UserAgentApplication(idApp, null, null, {});
Call loginPopup:
msUserAgent.loginPopup(['user.read'])
.then((res) => console.log(res))
.catch((err) => console.log(err));
after set my credentials, popUp not closing, but redirect to main page. Then and catch not called at all.
Issue on github about this: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/174
After redirect, my URL (in popup) has id_token (jwt-token), but this page doesn't have initialized msUserAgent yet. It dynamically process, I initialize msUserAgent after user click (idApp getting from backend)
Question:
Can I get access_token when I have id_token (jwt-token) by using MSAL lib?
Thanks
for getting access_token need to do next:
On page where you are being redirected. You need to have loaded MSAL script
msUserAgent need to auto init after all scripts will be loaded
MSAL checking if JWT token present in uri (after redirect), and if it exists, immediately send silent request and get access_token and save to sessionStorage (you can change to localStorage in options)
Related
I am trying to access the fitbit API through oAuth on react-native. User login via fitbit works and after this, localhost is redirected and the access token is shown within the endpoint on the browser.
The issue i am facing currently is how can i get this access token from the browser in order to start fetching data from the fitbit api using the users access token within an android react-native application?
I am currently generating the oauth url and allowing the user to login. The issue is that after login is successful, there is no way i can retrieve the access token.
function OAuth(client_id, cb) {
const oauthurl = `https://www.fitbit.com/oauth2/authorize?${qs.stringify({
client_id,
response_type: "token",
scope: "heartrate activity activity profile sleep",
redirect_uri: "http://localhost",
expires_in: "31536000",
})}`;
console.log(oauthurl);
// Linking.openURL(oauthurl).catch((err) =>
// console.error("Error processing linking", err)
// );
}
After login is successful, this is the url i get back in the browser which contains the access token:
http://localhost/#access_token=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyM0JCSzUiLCJzdWIiOiI5TEJSUEMiLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4i2IK2F0fX1UuuIwZDbc4&user_id=9LBRPC&scope=sleep+heartrate+profile+activity&token_type=Bearer&expires_in=31534747
As mentioned previously, how can i get this access token back into my application to be used?
Im working on a project, using firebase auth for login i.e. login with google; if logged in then redirect to /app where real functionalities of webapp exists.
login page js:
document.getElementById('login').addEventListener('click', e => {
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth()
.signInWithPopup(provider)
.then((result) => {
firebase.auth().currentUser.getIdToken(true).then(function(token) {
// make request to backend to get /app page where main app exists
axios.get('/app', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => {
console.log(res.data);
});
});
});
});
now my main motive is, user can't access pages other than / (landing page) without JWT token in header.
so here when user log in using login With google it will give token when logged in and then it will make req to backend with token and backend will return /app page pre-rendered!
PROBLEM: using this is code, when i make req to backend it just return HTML code in res.data BUT i want actual page!!
Axios is well and good to fetch data from my backend api but i cant figure out how to attach header and make req, And get page instead of source code in response;
Same problem is occurring everywhere in application. I just don't want users to access pages other than landing page without JWT in header!
backend: nodeJs
firebase auth
ejs template engine for view
EDIT:
meaning of returning source code is:
img of console log
any help, ideas or approach are welcome 🙏🏻
Login as before
Write the token into a cookie instead of the Authorization header
Redirect the browser to /app
In the backend read the cookie instead of the Authorization header
This way the browser will solve the problem for you by rendering the response. Using cookies is the usual way to implement a login without AJAX.
It's not possible to make a redirect and set the Authorization header.
I'm creating an website where users can load another website i'm developing after logging in. When authorized, the users gets a JWT token, and this token is sent in the header with every request, just like any webapplication with JWT token authorization.
The problem is that I only want to send the sensitive page content to the user that is authorized. The authorization in the backend is already working with normal API calls, but I can't intercept calls made by the system itself when encountering a "src" tag for example.
The HTML file is requested like this (for convenience the header token is added here instead of in a seperate interceptor file):
redirect(response) {
console.log(response);
if(response.isAdmin) {
const headers = new HttpHeaders().set("Authorization", "Bearer " + response.token);
this.http.get("AdminPage", {headers: headers, responseType: "text"}).subscribe(response => {
// response is the HTML file
const win = window.open("", "_self");
win.document.documentElement.innerHTML = response;
});
} else {
// The users page will be loaded here just like above, with another path
// TODO
}
}
The HTML file is loaded, but when it encounters the "src" tags in it, it will request the files from the server, but the server won't respond because there is no JWT token in the request.
Is there any way to intercept this calls too? Or is there a better way to accomplish this?
(I don't know if its relevant, but my backend is written in ASPNET.Core)
You can put it as Get parameter like that
<img src="http://img.com?token=<token>"/>
Or you can use cookies like #matt suggested
It turns out it is really easy. You can just store your JWT token inside a cookie using the following code inside the controller in the backend (in ASPNET.Core):
CookieOptions cookieOptions = new CookieOptions();
cookieOptions.HttpOnly = true;
Response.Cookies.Append("auth_token", user.Token, cookieOptions);
And you can retreive the token inside the authorization middleware like this:
string token = context.Request.Cookies["auth_token"];
It is also more secure then storing it inside local/session storage because of XSS attacks.
I've read about it here:
https://www.c-sharpcorner.com/article/asp-net-core-working-with-cookie/
And here:
https://blog.logrocket.com/jwt-authentication-best-practices/
With the cookie, you don't even need to intercept the http request in the frontend, because the cookie is sent automatically with every request.
credits to #Matt Davis
I'm using web firebase javascript to authenticate by email and password. This process generates a token which I use to verify on my nodejs backend using firebase-admin. Once this token is generated, I store it on the browser local/session storage.
The front end is AngularJs which I intercept the http request to inject the token stored within the browser.
This is working fine, however after a while this token expire. So what would be the best way to refresh this token before it sends to the nodejs api?
Note: should I requet the currentUser.getToken() every request?
The currentUser.getIdToken() only refreshes the token when the current token has expired! So it doesn't create unneeded traffic or requests to Firebase!
firebase.auth().currentUser.getIdToken(true) // here we force a refresh
.then(function(token) {
// ... do stuff!
}).catch(function(error) {
if (error) throw error
});
You'll see that I added true as an argument to the getIdToken() function. This forces a refresh!
Here is the Firebase Documentation for the getIdToken() function.
I hope that helps!
I am just having fun with the new Firebase, but I'm struggling with auth system.
Because I'm trying to login user from options page of google extension, so I can't use signInWithPopup or Redirect method due (some) security reasons.
So I figure out possible solution. From options page I redirect user to my another page, where he can easily login with Firebase (by Facebook provider) - everything is OK - user obtain OAuth FB token and this page send message to extension to cache this token.
There lies the problem.
I have code like this:
firebase.initializeApp(FIREBASE_CONFIG);
var credential = new firebase.auth.FacebookAuthProvider.credential(token);
firebase.auth().signInWithCredential(credential)
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err.code);
})
This fire up POST request to https://www.googleapis.com/identitytoolkit/v3/relyingparty/ and in response I can clearly see the error:
message:"INVALID_REQUEST_URI"
This request is fired with requestURI payload, which is in mine situation:
chrome-extension://kefhjfjilmodblnpnekjleceapohasdf/options.html
When I tried to fire this request from terminal with CURL and I faked the requestURI with 'http://localhost' everything is OK and I got correct data.
Do you have any ideas, how can I achieve proper behavior?
Thanks a lot.
P.S: I'm using Firebase.js 3.0.5-rc.2