OAuth
Terms
- Authorization code: a value returned in the authorization code flow that is exchanged by the client for an access token. The authorization code cannot be used for anything else.
- Authorization server: presents the UI for the user to approve the access request. May be the same as the resource server.
- Access token: a token used on subsequent requests to give access to data.
- Client: the application attempting to get access to the user's account
- Client ID: an identifier for the client. Public information.
- Client secret: a private bit of information to confirm the client's identity. Can only be kept secret for server-rendered applications.
- Code challenge: the base-64 encoded version of the hash of the code verifier.
- Code verifier: the original random string generated in the PKCE flow.
- PKCE: "Proof Key for Code Exchange". First used to secure native apps, now recommended for frontend JS and server apps as well, for additional security.
- Redirect URI: a valid URL for the user to be redirected back to after the authorization code grant flow
- Refresh token: allows retrieving new access tokens without presenting a UI to the user
- Resource server: the API
- Resource owner: the user
- Scope: indicates which groups of the user's data the client is requesting access for
- State: a string sent by the client used to verify the response
Grant Types
Client Credentials
- Used for machine-to-machine authentication
- Providing username and password directly to API
- One-legged: responds with access token directly
Resource Owner Password Credentials Grant (Password Grant)
- Client ID, client secret, user's login and password
- One-legged
- Best used for trusted clients; would not be used for a third-party app (because it allows the third party to snoop on the user's credentials)
Authorization Code Grant
- Mobile Authorization Code Flow
- Example: signing into a third party site via central Auth service like Facebook, Google, Twitter, GitHub
- Central service gets redirect URL
- User sent to central service, log in, redirected back to third party app with an authorization code
- Auth code sent with client ID and secret to get access token
- Why? Because a man in the middle attack can intercept this authorization token, but this way they can't use it unless they also have the secret from the server.
- Three-legged
PKCE
- Client makes up and stores a one-time secret: the code verifier
- Client hashes the code verifier: the code challenge
- Client tells the server the code challenge and algorithm
- Server stores the code challenge and algorithm for the auth code it generates
- On auth code redemption, client tells the server the unhashed code verifier
- Server hashes the code verifier and ensures the hash matches the code challenge it previously sent
Implicit Grant
- Do not use; security issues: access token available in URL to client, instead of only seen on server
- Access token directly
- Used by clients where you can't protect your secret, like a frontend webapp
Security Features
- Only issue short-lived access tokens, like an hour
- Refresh tokens that are longer-lived (Alex suggested indefinitely)
- Have to resend the secret
- Does that mean doesn't provide security benefit for client-side apps? Alex says correct
- Sometimes no refresh tokens used, access tokens live indefinitely
Questions
Why do you need a server?
- To store a secret, so you can use the authorization code grant
- Why? Because without a secret you're vulnerable to a MitM attack, but with a secret you aren't.
- Why? (TBD)
- Would it be worth it to create a server just to store the secret, even if there is no other server functionality? (TBD, test this)
- Why return cookie to user, instead of access token (from third party service)?
- Server-rendered app can use CSRF, SPA can't easily
- Alex didn't have a good answer
Implementations
- Doorkeeper - provider for Rails
- Passport.js - provider for Node
- client-oauth2 - client for frontend webapps
- react-native-app-auth - client for RN including PKCE support
- expo-auth-session - client for Expo
Slapdash