bumpy-controller-43157
04/09/2025, 9:18 AMbrief-egg-61061
04/09/2025, 9:19 AMbrief-egg-61061
04/09/2025, 9:19 AMbumpy-controller-43157
04/09/2025, 9:19 AMbrief-egg-61061
04/09/2025, 9:19 AMbrief-egg-61061
04/09/2025, 9:20 AMory create oauth2-client --token-endpoint-auth-method none
2. Implement PKCE in your React application: javascript // Generate PKCE code challenge and verifier async function generatePKCES256() { const array = new Uint8Array(64) crypto.getRandomValues(array) const codeVerifier = Buffer.from(array).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") const codeChallenge = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)).then((buffer) => { return Buffer.from(buffer).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") }) return { codeChallenge, codeVerifier } } const { codeChallenge, codeVerifier } = await generatePKCES256() const clientId = "your_client_id" const redirectUri = "<https://your-app.com/callback>" // Redirect to authorization endpoint const authorizationUrl = `https://$<http://PROJECT_SLUG.projects.oryapis.com/oauth2/auth?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&scope=openid&state=12345&code_challenge_method=S256&code_challenge=${codeChallenge}|PROJECT_SLUG.projects.oryapis.com/oauth2/auth?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&scope=openid&state=12345&code_challenge_method=S256&code_challenge=${codeChallenge}>` window.location = authorizationUrl
3. Exchange the authorization code for tokens: javascript const code = new URLSearchParams(window.location.search).get("code") const tokenUrl = "https://$<http://PROJECT_SLUG.projects.oryapis.com/oauth2/token|PROJECT_SLUG.projects.oryapis.com/oauth2/token>" const requestBody = `grant_type=authorization_code&client_id=${clientId}&code_verifier=${codeVerifier}&code=${code}&redirect_uri=${redirectUri}` fetch(tokenUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: requestBody, }) .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error(error))
This implementation follows the SPA and public client with PKCE pattern as described in [Ory's OAuth2 Authorization Code flow documentation](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow#spa-and-public-client-with-pkce). ## Backend Implementation (Spring Boot) For your Spring Boot backend: 1. Validate tokens: Your backend should validate the access tokens sent by the frontend by introspecting them against Ory's token introspection endpoint. 2. Secure APIs: Use the validated tokens to authorize access to your protected resources. ## Important Security Considerations 1. Use PKCE: As you're implementing a SPA, using PKCE is essential as it prevents code interception attacks [as described in Ory's blog](https://www.ory.sh/blog/oauth2-for-mobile-app-spa-browser). 2. Avoid Resource Owner Password Credentials Flow: Ory explicitly recommends against using this flow as mentioned in their [OAuth2 for Mobile Apps and SPAs blog](https://www.ory.sh/blog/oauth2-for-mobile-app-spa-browser). 3. Consider using AppAuth: For a more robust implementation, consider using [AppAuth](https://appauth.io/) as recommended by Ory for client-side implementations. 4. Store tokens securely: Store tokens in secure HTTP-only cookies or other secure storage mechanisms. While the knowledge sources don't provide specific Spring Boot integration details, you can use standard OAuth2 client libraries for Spring Security to validate the tokens issued by Ory. For more detailed guidance, refer to [Ory's documentation on OAuth2 and OpenID Connect](https://www.ory.sh/docs/oauth2-oidc/authorization-code-flow) and their [frontend framework integrations](https://www.ory.sh/docs/welcome).