careful-honey-27437
04/12/2025, 2:08 AMbrief-egg-61061
04/12/2025, 2:08 AMbrief-egg-61061
04/12/2025, 2:08 AM/sessions/whoami
endpoint, Ory will look for authentication in multiple places: - It checks for an Ory Session Cookie in the Cookie
HTTP header - It checks for an Ory Session Token in the X-Session-Token
HTTP header - It checks for an Ory Session Token in the Authorization: bearer <token>
HTTP header This means your API needs to be prepared to handle both authentication methods, depending on what type of client is connecting to your service. For browser clients, you'll typically forward cookies, while for native applications, you'll need to handle the session token. As the documentation states: > This endpoint authenticates users by checking: > - if the Cookie
HTTP header was set containing an Ory Kratos Session Cookie; > - if the Authorization: bearer <ory-session-token>
HTTP header was set with a valid Ory Kratos Session Token; > - if the X-Session-Token
HTTP header was set with a valid Ory Kratos Session Token. [Ory API Reference](https://www.ory.sh/docs/reference/api) For server-side applications, you would typically forward the cookie header: js router.get('/protected-endpoint', async function (req, res) { const session = await client.toSession(undefined, req.header('cookie')) console.log(session) })
For non-browser applications, you would use the session token: js const session = await client.toSession("the-session-token") console.log(session)
This dual approach allows Ory to provide a secure authentication system that works across different types of applications while maintaining the same security model.careful-honey-27437
04/12/2025, 2:09 AMcareful-honey-27437
04/12/2025, 2:10 AMbrief-egg-61061
04/12/2025, 2:10 AMbrief-egg-61061
04/12/2025, 2:10 AMgo package main import ( "context" "fmt" "os" client "<http://github.com/ory/kratos-client-go|github.com/ory/kratos-client-go>" ) func main() { configuration := client.NewConfiguration() configuration.Servers = []client.ServerConfiguration{ { URL: "<http://127.0.0.1:4433>", // Kratos Public API }, } apiClient := client.NewAPIClient(configuration) // Get the cookie from the request header cookie := request.Header.Get("Cookie") // Pass the cookie to the toSession method resp, r, err := apiClient.FrontendApi.ToSession(context.Background()).Cookie(cookie).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `FrontendApi.ToSession``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } // Use the session data fmt.Fprintf(os.Stdout, "Traits: %v\n", resp.Identity.Traits) }
### Using Ory Session Tokens (Native Applications) For native applications, you would use the session token: go package frontend import ( "context" "fmt" "os" "<http://github.com/ory/client-go|github.com/ory/client-go>" ) type oryMiddleware struct { ory *ory.APIClient } func init() { cfg := client.NewConfiguration() cfg.Servers = client.ServerConfigurations{ {URL: fmt.Sprintf("<https://%s.projects.oryapis.com>", os.Getenv("ORY_PROJECT_SLUG"))}, } ory = client.NewAPIClient(cfg) } func CheckSession(ctx context.Context, sessionToken string) (session *client.Session, err error) { session, _, err = ory.FrontendApi.ToSession(ctx). XSessionToken(sessionToken). Execute() if err != nil { // error checking the session, for example due to expired token provided return nil, err } return session, nil }
### Middleware Example for Web Applications Here's a more complete middleware example that checks for valid sessions in a web application: go package main import ( "context" "errors" "log" "net/http" ory "<http://github.com/ory/client-go|github.com/ory/client-go>" ) func (app *App) sessionMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { log.Printf("handling middleware request\n") // This example passes all request.Cookies to `ToSession` function. cookies := request.Header.Get("Cookie") // Look up session. session, _, err := app.ory.FrontendAPI.ToSession(request.Context()).Cookie(cookies).Execute() // Check if a session exists and if it is active. if err != nil || (err == nil && !*session.Active) { // redirect the user to the login UI, in this case we use the default browser flow http.Redirect(writer, request, "/.ory/self-service/login/browser", http.StatusSeeOther) return } // Add the session details to the context for handlers to access. ctx := withSession(request.Context(), session) // Continue to the next handler (the dashboard in the simple example). next.ServeHTTP(writer, request.WithContext(ctx)) return } } func withSession(ctx context.Context, v *ory.Session) context.Context { return context.WithValue(ctx, "req.session", v) } func getSession(ctx context.Context) (*ory.Session, error) { session, ok := ctx.Value("req.session").(*ory.Session) if !ok || session == nil { return nil, errors.New("session not found in context") } return session, nil }
This middleware checks for a valid session using the cookie from the request. If the session is valid, it adds the session to the request context and continues to the next handler. If the session is not valid, it redirects the user to the login page. [Integrate authentication into Go](https://www.ory.sh/docs/getting-started/integrate-auth/go#validate-and-login) These examples demonstrate how to handle both Ory Session Cookies and Ory Session Tokens in Go applications, allowing you to authenticate users regardless of whether they're using a browser or a native application.careful-honey-27437
04/12/2025, 2:25 AMerr
that may result from the FrontendAPI.ToSession
function indicate an invalid session, or just an error in obtaining the session?brief-egg-61061
04/12/2025, 2:25 AMbrief-egg-61061
04/12/2025, 2:26 AMerr
returned from the FrontendAPI.ToSession
function can indicate both an invalid session and errors in obtaining the session. Let me explain the different scenarios: When calling ToSession
, an error can occur in these main cases: 1. Invalid or expired session: If the session cookie or token is invalid, expired, or doesn't exist, the API will return a 401 Unauthorized error. This is the most common case and indicates that the user is not authenticated. 2. Insufficient authentication level: If the session exists but doesn't meet the required authentication assurance level (AAL), a 403 Forbidden error is returned. This happens when a user has authenticated with a lower level than required (e.g., only password when both password and second factor are required). 3. Technical errors: These could be network issues, server problems, or other technical difficulties in making the API call. From the documentation, we can see that the error response includes an id
field that helps identify the specific error: - `session_inactive`: No active session was found in the request - `session_aal2_required`: An active session was found but it doesn't fulfill the required Authenticator Assurance Level [Ory API Reference](https://www.ory.sh/docs/kratos/reference/api) Here's how you might handle these errors in Go: go session, r, err := app.ory.FrontendAPI.ToSession(request.Context()).Cookie(cookies).Execute() if err != nil { // Check if this is an authentication error (401) if r != nil && r.StatusCode == 401 { // User is not authenticated http.Redirect(writer, request, "/.ory/self-service/login/browser", http.StatusSeeOther) return } else if r != nil && r.StatusCode == 403 { // User is authenticated but needs to complete additional authentication steps // e.g., second factor authentication http.Redirect(writer, request, "/.ory/self-service/login/browser?aal=aal2", http.StatusSeeOther) return } else { // Some other error occurred (network, server, etc.) log.Printf("Error checking session: %v", err) http.Error(writer, "Internal Server Error", http.StatusInternalServerError) return } } // Session is valid and active if !*session.Active { // This is a rare case where we got a session but it's not active http.Redirect(writer, request, "/.ory/self-service/login/browser", http.StatusSeeOther) return } // Continue with valid session
This approach allows you to distinguish between authentication errors (invalid session) and technical errors, and handle each appropriately in your application.