authts / oidc-client-ts

OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
https://authts.github.io/oidc-client-ts/
Apache License 2.0
1.41k stars 214 forks source link

How to use existing token in a new usermanager instance without signinRedirect #1684

Open ept-Ayush opened 2 months ago

ept-Ayush commented 2 months ago

I am passing token , client _id and domain via query param. I want to use the token to get new token but I was not able to find any solution. I have to call signinRedirect again and do the same process for logging in and getting new token.

Is there any simple solution for this ?

@pamapa

pamapa commented 2 months ago

Existing access token and if used refresh token are stored either in the local or session storage.

Somthing like this, assuming you are using the default sessionStorage.

import { User } from "oidc-client-ts"

function getUser() {
    const oidcStorage = sessionStorage.getItem(`oidc.user:<your authority>:<your client id>`)
    if (!oidcStorage) {
        return null;
    }

    return User.fromStorageString(oidcStorage);
}
ept-Ayush commented 1 month ago

@pamapa Thanks for response but actually my main problem is let's say:

I have a website www.example.com where I am initiating the login via signinRedirect and there I am storing the data in localStorage there I have everything like token, refresh token and all the other details ( that is user is succesfully signed in) after sign in I have to send user to www.differentdomain.com there user is not logged in. so what I am doing is I am redirecting to second website with query param like www.differentdomain.com?token=someValidToken&clientId=someClientId&domain=someUserDomain now what exactly I want is if somehow I can use this token ( if its valid ) directly without calling signinRedirect again (may be siginsilent but it didn't work now) because right now on the other website I am doing the sign in process again internally as at that time it will not have any localstorage or cookies as it is entirly different domain.

Like somehow if there is any simplerway so that it would work without calling the authentication endpoint again.

pamapa commented 1 month ago

Hard to say. But typically access tokens are bound to the domain and i can't know if the access token would work for both domains. If you have a valid user (access, refresh token and claims), you can also inject it into your localStorage (oidc.user:<your authority>:<your client id>) before setting up the UserManager. When you need to do that, this means <your authority> or <your client id> is different, thus i doubt this would work. If they match, you do not need to copy and it might work automatically.

ept-Ayush commented 1 month ago

@pamapa Actually both are our domain but they are seperate domains. About the injecting part (oidc.user:<your authority>:<your client id>) the authority and client id are same in the new one as well but I am wondering is there any function/method to create the same response as we get in Usermanger.getUser from the access token itself as that response contain a lot of things?

Might be probably then it can work without attempting to login again

Badisi commented 1 month ago

@ept-Ayush, I think you are approaching the problem from the wrong angle. Each web app should be registered individually in your IDP. They represent separated clients, and tokens from one client cannot be used with other clients (the IDP will reject them). You should instead look for SSO or put both clients under the same realm so that the user session can be used for both (i.e. the first client log-in, creates the session and when the second client needs to log-in as well, it reuses the session, so no need to authenticate).

Plus, security wise, you shouldn’t be passing the tokens as query parameters. This was used in the past in the implicit flow, but has since be deprecated as it is not secured. Same with storing tokens in the local storage, it is not considered secured and should be avoided if possible (if you can, prefer storing tokens in the app memory and use sign-in silent to regain access from the current session, if any)

ept-Ayush commented 1 month ago

Actually my hands are tied. I have different domains. I agree with your points that each idp should use different client id . Ultimately I want to create the SSO itself, to create that i have added domain A as login server and other domain B, C will go through A to get the login data.

For the localstorage I am using it to use same session in multiple tabs.

if somehow I can create the same response as pampa said I can achieve the things.