I guessing that I can authenticate/authorise an AP...
# share-your-work
h
I guessing that I can authenticate/authorise an API only application, with API authentication keys with SuperTokens but I'm not sure how. how can I create a API key to use for API requests to my app? I can create users using /recipe/signup but not sure how to create an access token that does not expire
r
hey @helder.rossa checkout the jwt recipe in the core. You can create JWTs with any expirythat you like.
h
I'm doing this https://supertokens.com/docs/microservice_auth/jwt-creation#what-to-do-with-the-jwt and using verifySession() in the route of my app, and the output is :
Copy code
json
{
    "message": "unauthorised"
}
r
verifySession is for use with session recipe. Not with JWT recipe.
For verification of JWTs, you should checkout https://supertokens.com/docs/microservice_auth/jwt-verification/index
h
Thanks, I was trying to find some utility to do the verification and ignored that code. So, after creating the JWT token like:
Copy code
sh
http :3567/recipe/jwt rid:jwt \
  payload:='{"uuid":"someid"}' \
  useStaticSigningKey:='true' \
  algorithm=RS256 \
  jwksDomain=http://localhost:3333 \
  validity=31556926000
I was hable to successfuly decode the JWT token and get the payload:
Copy code
sh
http -pb -j :3333/ Authorization:"Bearer $ACCESS_TOKEN"
{
    "jwt": {
        "exp": 33242658621,
        "iat": 1685732621,
        "iss": "http://localhost:3333",
        "uuid": "someid"
    }
}
thanks!
Altough this was not what I wanted. I want to create a user and have access tokens associated to that user. With possible having roles and such. So, I want a access token for a user
r
You can add a sub claim in the JWT and it would essentially become an access token for a user
You can also see our other recipes. Maybe they have the feature you want? I’m not fully sure what you are looking for
h
I just want a simple thing. A user access token (aka api key) that does not expires. And in the api side, the token becomes a session (user identification)
r
You could also use our session recipe and call createNewSession on the user id
The access token can be the api key
You could set the access token lifetime to a very very long value
And then use verifySession function in your APIs to verify it
h
OK... I'll try that. And thanks btw!
Im guessing I will use the
createNewSessionWithoutRequestResponse
method
r
Yes you need to use that.
h
not sure where to put the session ttl
r
Search our docs for session timeout
r
Yes
For your use case, you should just look at the session recipe https://supertokens.com/docs/session/introduction
h
I don't think that's a good policy to set ALL session timeouts in SuperTokens to a very very long value. 1. I want to have regular sessions, aka user logins, to expire has 'normal' (what ever timeout they should have). 2. Only API keys, need to be forever (or any other lifetime I could set to) Like, GitHub/GitLab personal tokens, and every other service online that has login and offers API keys to access their API. Is that so un uncommon thing to exist that I'm asking?
r
So then you should not use the session management feature for this, and use just the JWT recipe for rthis.
using which you can create JWTs that are long lived and add any claim to them
h
right, but I need to associate the user to that JWT and their roles (if exists). Let's say, a users uses the API key. I need to: 1. check the key is valid (we did this above with custom code) 2. check what user it is and if he has permissions to execute that resource
You siad, a sub claim, so I'm guessing I could set
"sub": "... user id..."
in the payload of the JWT
and now? another custom code to get the user?
r
yea so you can add all of those in the claims of the jwt
> another custom code to get the user? What do you mean?
h
I need to get the user and roles from the JWT. How?
r
once you add them as claims in the JWT, you can verify the JWT and just read the payload of it to get the sub claim and role claim
use any jwt verification lib
h
So, what you mean is that all the info will be in the JWT
r
yea. You will need to add it
since you will be creating the JWT using the JWT recipe
h
Aren't roles dynamic? I could add and remove roles in supertokens from a user?
r
then you should use the session recipe
if you want to issue API keys, use the JWT recipe
for normal logging in, use the sesson recipe
h
not sure where supertokens it's needed in this setup
r
it's all in our docs please. I would recommend that you go through it.
if you have any very specific question, then i can help 🙂
h
I've read the docs and I already read everything you have sent. I really appreciate your help, time and patience. But what you are saying about it's all in the it's not true.
r
with the JWT recipe, you need to add the payload yourself
with the session recipe, it gets added on its own
jwt recipe is ONLY meant to create JWTs for whatever purpose
here, you wanted to create API keys that are very long lived, i suggested that you use the session recipe (which will contain all the info about the user), but then you didn't want to change the lifetime for all the sessions, which is fair.
So instead, you can use the JWT recipe to make your own JWTs.
which is independent to the session recipe
h
I was really trying to evaluate SuperTokens, but I guess is not the tool I need. That's fair also. I'm able create API keys with Keycloak, Auth0, etc. And even my current setup has that implemented. Not sure why we could not pass the TTL to
createNewSessionWithoutRequestResponse
method. Because that would clearly resolve this issue. In my current tool I just create an access token to an user with -1 (infinite) TTL and that' it. So, it's not possible, but I think it should. But even the JWT solution, we have to bare that roles (or any other user information) are dynamic, and so, that information should not be in JWT. But the user ID it could be the only information needed here. And then I could retrieve the user and roles from SuperTokens after. That's what I wanted help on. I don't mind to do custom code in my app to get this information and then I could use
roles.includes("admin")
like stated in the docs. I'm sure, that more people will ask for this feature (I've read other threads in Discord) and I think it's not clarified in the docs how to do user API keys. Even if you think that's all in the docs. With that said, thanks!
r
So this is something we do intend to solve for yea
I’m the meantime, you could create a new session using the session recipe, and then take the claims from them (except for iat and exp) and then copy over those claims in the createJWT function with whatever expiry you want
And then you should also be able to continue to use verifySession on it.
Give it a shot please.
h
OK, I will. I don't mind SuperTokens don't having feature X or Y. But I do care about helping in the right way and that you are aware of the feature, and even better, addressing the issue in the future. If you don't mind, I will get in touch about thins again if I'm lost. Thanks!!
r
Yea sure. Allowing createNewSession to take an access token lifetime is definitely something we want to add in the future. But I’m the meantime, the method I suggested should work.
h
have you said something like this?
Copy code
javascript
const userId = 'b5148681-ef9b-44b1-adf0-36e933300af3'; // get from db

const session = await Session.createNewSessionWithoutRequestResponse(userId);

const tokens = session.getAllSessionTokensDangerously();
if (tokens.accessAndFrontTokenUpdated) {
  const payload = await session.getAccessTokenPayload();
  delete payload.exp;
  delete payload.iat;

  const jwt = await createJWT(payload, 31556926000);

  return res.send({ jwt: jwt });
}
the payload has plenty of information:
Copy code
json
{
  "sub": "b5148681-ef9b-44b1-adf0-36e933300af3",
  "exp": 1685906515,
  "iat": 1685902915,
  "sessionHandle": "04d312e2-c0cd-4744-829a-30b821c50165",
  "refreshTokenHash1": "19b507658cda61bfd80013c6f2ba3c68d410e530284f647316b817ee4b28a9f4",
  "parentRefreshTokenHash1": null,
  "antiCsrfToken": null,
  "iss": "http://localhost:3333/api/auth"
}
won't the session store the expiration time in database also?
r
This is exactly what I meant. The expiration time of the refresh token is stored, and not the access token’s expiry - since the access token is stateless anyway
h
doesn't seems to be working:
Copy code
javascript
await server.get(
  '/',
  {
    preHandler: verifySession(),
  },
  async (req: SessionRequest, res) => {
    let session = req.session;
    res.send({ session });
  }
);
Copy code
sh
http -pHb -j :3333/ Authorization:"Bearer $ACCESS_TOKEN"
GET / HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Bearer eyJraWQiOiJzLTgx...uh4Mc3AxqpXUA
Connection: keep-alive
Content-Type: application/json
Host: localhost:3333
User-Agent: HTTPie/3.2.2

{
    "message": "unauthorised"
}
The error is: "JWT header mismatch"
because the header does not have version property
r
oh yea. We are working on this fix. Should be available sometime this week.
after that, it should work
h
@rp_st any news about this fix? thanx
r
should be released this week.
h
what should I be expecting? - a new docker hub image release? - a new release of the nodejs sdk?
r
A new version of the node SDK
The release got delayed this week.
Should be out next week though
h
next week right?
r
It’s released already
Sorry. Didn’t update this
You will also have to update the supertokens core for this to the latest version. (Make sure to see our supertokens-code Changelog and follow the migration steps)
h
Copy code
json
{
    "error": "Unauthorized",
    "message": "The access token doesn't match the useDynamicAccessTokenSigningKey setting",
    "statusCode": 401
}
r
You will need to set the useDnamicAccessTokenSigningKey setting to false in the session.init on the backend
h
Copy code
javascript
await createJWT(payload, undefined, true)
or
Copy code
javascript
Session.init({ useDynamicAccessTokenSigningKey: false, })
accepted the ACCESS_TOKEN but.... no
req.session
!!!
r
Setting it to false is the fight the correct thing to do
Req.session is the result of using verifySession middleware
Or the getSession function
h
i'm using
Session.getSession(...)
r
This function returns the session object
h
I'm using
addAuthorizationHooks()
that then uses
Session.getSession(...)
but I'm not getting a session
r
I mean that function needs to be awaited and it returns a session object. Or else it throws an error
So you should see what the returned value is
h
dumb me... I'm using this code:
Copy code
javascript
      const session = await Session.getSession(req, reply);
      if (!session) {
        throw new Error();
      }
r
So did it work?
h
still an error...
The access token doesn't match the useDynamicAccessTokenSigningKey setting
should this be true or false? 🙂
Copy code
javascript
... await createJWT(payload, undefined, true)
r
Keep it false
In session.init
And in createJwt
h
the same...
The access token doesn't match the useDynamicAccessTokenSigningKey setting
r
Did you make a new access token with the setting being false?
h
everytime I restart the app... I'm creating a new access token... and testing it again
r
Can I see session.init config?
h
I think I got it working
createJWT(payload) works
r
Right. Passing false to the second arg should have also worked
Actually, I don’t recall with the second arg is for
h
validitySeconds
by default it's 1y
r
Right. So passing false to the 3rd arg should have also worked.
h
I guess I was changing to much things at same time :-p
OK... I'll to get this working from this. Maybe I'll put the code in GitHub for reference in a coulpe of days
humm... the session object does not have the user email
r
That’s expected. You have the user id using which you can fetch their email
See our docs for that
h
ok ok.. thanks, I'll do that.
i've got to this:
Copy code
json
{
    // custom info in session database
    // when JWT was created
    "data": { 
        "apikey": true 
    },
    "email": "user@example.com",
    "id": "b08937a7-fb50-4e45-a30d-b70be20135c5",
    // UserRoles associated with the user
    "roles": [ 
        "admin"
    ]
}
I guess I'm in the right way. Thanks !!!
r
oops mistkae
q
@rp_st is there any way to show the generated JWT in the dashboard?
r
which dashboard?
q
the one defined by the recipe
at
/auth/dashboard
r
we don't show that
q
alright. thanks
3 Views