The Authorize Endpoint
The /authorize endpoint starts the authorization procedure and issues an authorization code.
This endpoint operates through the browser of the user. The Client redirects the user here, and your server redirects the user back to the Client. Thus each parameter is visible in the URL, the browser history keeps it, and the user can change it. Never send the client secret to this endpoint.
INFO
You need this endpoint for the authorization code grant and the implicit grant.
Accept the GET method for the initial request. Redirect the user agent to your authorization page.
You can change the URL.
/oauth/authorizeand/v1/authorizeare two other common names.
Flow
- The Client redirects the user to
/authorize. - Your server authenticates the user, if the user is not authenticated already.
- Your server shows a consent screen. The user approves or denies the request of the Client.
- If the user approves, your server redirects the user to the Registered Redirect URI with an authorization code.
- The Client sends the authorization code to the
/tokenendpoint and receives an Access Token.
You can also add other checks, such as 2FA, MFA, or CAPTCHA, in the same handler.
Implementation
import {
requestFromExpress,
handleExpressResponse,
handleExpressError,
} from "@jmondi/oauth2-server/express";
app.get("/authorize", async (req: Express.Request, res: Express.Response) => {
try {
// Validate the HTTP request and return an AuthorizationRequest.
const authRequest = await authorizationServer.validateAuthorizationRequest(
requestFromExpress(req),
);
// You will probably redirect the user to a login endpoint.
if (!req.user) {
res.redirect("/login");
return;
}
// After login, the user should be redirected back with user in the session.
// You will need to manage the authorization query on the round trip.
// The auth request object can be serialized and saved into a user's session.
// Once the user has logged in set the user on the AuthorizationRequest
authRequest.user = req.user;
// Once the user has approved or denied the client update the status
// (true = approved, false = denied)
authRequest.isAuthorizationApproved = getIsAuthorizationApprovedFromSession();
// If the user has not approved the client's authorization request,
// the user should be redirected to the approval screen.
if (!authRequest.isAuthorizationApproved) {
// This form will ask the user to approve the client and the scopes requested.
// "Do you authorize Jason to: read contacts? write contacts?"
res.redirect("/scopes");
return;
}
// At this point the user has approved the client for authorization.
// Any last authorization requests such as Two Factor Authentication (2FA) can happen here.
// Redirect back to redirect_uri with `code` and `state` as url query params.
const oauthResponse = await authorizationServer.completeAuthorizationRequest(authRequest);
return handleExpressResponse(res, oauthResponse);
} catch (e) {
handleExpressError(e, res);
}
});More Endpoints
The handler above redirects to two routes. You must write these two routes.
Login Endpoint
app.get("/login", (req, res) => {
// Render login form
});
app.post("/login", (req, res) => {
// Authenticate user
// If successful:
req.session.user = authenticatedUser;
res.redirect("/authorize"); // Redirect back to authorize endpoint
});Scopes Consent Endpoint
app.get("/scopes", (req, res) => {
const authRequest = req.session.authRequest;
// Render consent form with client info and requested scopes
});
app.post("/scopes", (req, res) => {
const authRequest = req.session.authRequest;
authRequest.isAuthorizationApproved = true; // or false if denied
req.session.authRequest = authRequest;
res.redirect("/authorize"); // Redirect back to authorize endpoint
});Request Parameters
| Parameter | Required | Description |
|---|---|---|
response_type | Yes | Set to code for the authorization code grant, or token for the implicit grant |
client_id | Yes | The Client that requests the authorization |
redirect_uri | Conditional | The destination of the redirect. It must match a Registered Redirect URI exactly. You can omit it only when the Client has one Registered Redirect URI |
scope | No | The scopes that the Client requests |
state | Recommended | An opaque value. The server returns it on the redirect. Use it as your CSRF token |
aud | audience | No | The server records this value on the authorization request and encodes it into the authorization code. The aud claim (RFC 7519 §4.1.3) of the Access Token comes from the /token request |
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.comProtect your login form and your consent form against CSRF
The library validates the OAuth parameters. But your login route and your consent route are usual web forms, and the library does not protect them. Keep the life of the session that holds the AuthorizationRequest short.
Supports the following RFCs