The endpoint for login (or subsequently grabbing refresh tokens) within your Identity instance is ‘/token’. This can be POST to with either an email+password or refresh token credential method.
Here’s how the endpoint is being called in the GoTrue-JS library -
And here’s a bit more info on the GoTrue repo, under “POST /token” header -
Basic steps -
On your login page, have a handler function for the login form that
calls the login serverless function (passing the email + password)
handles successful returns
handles returned errors
In the login serverless function
parse email and password from the POST request
recreate some version of the function example above (from GoTrue-JS) that calls the /token endpoint with email + password
if successful, decide how you’d like to return and/or store the access token and refresh token
e.g. the function could return the JWT access token as a cookie and handoff the refresh token to another serverless function that saves it to a user database so this never hits the client
if fails, return error
Beyond this, you’ll need to also decide -
How you want to provide/control access to the auth’d sections of your site within your app now that you have a valid access token (in the JWT).
The answer for this can vary a bit depending on how you’re building your app
Where to safely store the JWT for subsequent use and also avoid malicious JS.
This is commonly done in an httpOnly/secure cookie that JS can’t access but your approach may vary depending on how you want to be able to access it later.
The choice is a bit trickier when there isn’t a server to help process and utilize cookie values. You don’t want client JS to be able to unsafely access the JWT (e.g. localstorage) but at some point, JS needs to be able to use it to make authorized requests. Definitely take time to consider/research this choice so you don’t accidentally open yourself up to security issues (like XSS and CSRF).
One method might be to call a separate ‘authenticate’ serverless function that serves as a pseudo middleware - parsing cookies, attaching the JWT to the header as a bearer token, and then passing the request to the target serverless function that requires authorization (e.g. getting user data from a database). But this seems pretty wasteful and un-performant. I’m currently trying to sort out other options on this front as well.
How/when to use the JWT for other authorized calls (e.g. load specific user content via another serverless function)
If you pass the JWT as an authorization bearer token (done in the request header) to a Netlify serverless function, it will provide you the context for that user in the function and also allow additional admin methods.
I’m definitely still piecing a lot of this puzzle together myself, but I hope this helps.
@Clayton , thank you for coming back and sharing such a tremendously detailed series of steps. This will be very beneficial for future Forums members who encounter something similar. Knowledge sharing is what makes the Forums great