<@U04UQ68083H> Hello! New to Ory, loving the produ...
# ory-copilot
s
@chilly-king-10285 Hello! New to Ory, loving the product so far. We’re using Ory Network to authenticate users on our Golang backend, the interface to which is CLI based. Right now the middleware is validating a session token passed in the authorization header using:
Copy code
func (m *oryMiddleware) oryValidateToken(token string) (*ory.Session, error) {
	session, _, err := m.oryClient.FrontendAPI.ToSession(context.Background()).
		XSessionToken(token).
		Execute()
	if err != nil {
		return nil, err
	}
my question is, where do I get a session token from for a new user? The ideal flow is that we check for a sessionToken in the CLI and if it doesn’t exist, output a link where they can login on the webui, which should return a sessionToken to the CLI (which can then be passed to the backend). I’m not able to find a way to get a sessionToken from the docs however
c
A message from kapa.ai
Hello! I'm glad to hear that you're enjoying Ory! In Ory, a session token is issued when a user authenticates through a client other than a web browser. This is particularly useful for native applications such as desktop applications, mobile applications, or terminal-based apps that do not run inside a browser. To get a session token, you would typically have your users authenticate through your application's login flow. Once authenticated, a session token is issued and can be used to authenticate subsequent requests. Here's an example of how you might check the current session using a session token in Go:
Copy code
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 revoking the session, for example due to expired token provided    return nil, err    }       return session, nil   }
(Source: [Ory Documentation](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-token)) In your case, you would need to implement a login flow in your CLI application that authenticates the user and retrieves the session token. This might involve redirecting the user to a web-based login page and then capturing the session token once it's issued. I hope this helps! Let me know if you have any other questions.
s
can I login with cURL instead and get a sessionToken as a response? @chilly-king-10285
c
A message from kapa.ai
Yes, you can use cURL to initiate a login flow and complete it, which will return a session token in the response. Here's an example of how you might do this:
Copy code
bash # Inits a Login Flow   actionUrl=$(    curl -s -X GET -H "Accept: application/json" \    "<https://playground.projects.oryapis.com/self-service/login/api>" \    | jq -r '.ui.action'   )      # Complete Login Flow with password method   curl -s -X POST -H "Accept: application/json" -H "Content-Type: application/json" \    -d '{"identifier": "your-email", "password": "your-password", "method": "password"}' \    "$actionUrl" | jq
In the response, you should see a
session_token
field. This is your session token, which you can use to authenticate subsequent requests. Please replace
"your-email"
and
"your-password"
with the actual user's email and password. (Source: [Ory Documentation](https://www.ory.sh/docs/kratos/self-service/flows/user-login#api-clients))
s
@chilly-king-10285 how would I do it in golang?
c
A message from kapa.ai
To initiate and complete a login flow in Go, you can use the Ory SDK. Here's an example of how you might do this:
Copy code
go package main  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 CreateLogin(ctx context.Context) (*client.LoginFlow, error) {  flow, _, err := ory.FrontendApi.CreateNativeLoginFlow(ctx).Execute()  if err != nil {   return nil, err  }   return flow, nil }  func CompleteLogin(ctx context.Context, flowId string, identifier string, password string) (*client.Session, error) {  body := client.UpdateLoginFlowBody{   Identifier: &identifier,   Password:   &password,   Method:     "password",  }  session, _, err := ory.FrontendApi.UpdateLoginFlow(ctx).Flow(flowId).UpdateLoginFlowBody(body).Execute()  if err != nil {   return nil, err  }   return session, nil }  func main() {  ctx := context.Background()   // Initiate a login flow  flow, err := CreateLogin(ctx)  if err != nil {   panic(err)  }   // Complete the login flow  session, err := CompleteLogin(ctx, *flow.Id, "your-email", "your-password")  if err != nil {   panic(err)  }   // The session token is now available  fmt.Println("Session token:", *session.Token) }
In this example, replace
"your-email"
and
"your-password"
with the actual user's email and password. The
CreateLogin
function initiates a login flow, and the
CompleteLogin
function completes the login flow with the password method. The session token is then printed to the console. Please note that this is a simplified example and you might need to adjust it to fit your specific use case. (Source: [Ory Documentation](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#create-login-flow))
s
@chilly-king-10285 my session token looks like ory_st_TOKEN, do I need to strip ory_st_ or anything else?
c
A message from kapa.ai
No, you don't need to strip the
ory_st_
prefix from your session token. The
ory_st_
prefix is used by Ory to easily identify and distinguish session tokens from other types of tokens. When you use the session token to authenticate requests, you should use the entire token, including the
ory_st_
prefix. (Source: [Ory Documentation](https://www.ory.sh/docs/security-compliance/token-formats#ory-session-tokens))
s
@chilly-king-10285 I get 401 unauthorized from the backend. I’m not running the CLI proxy, should I be?
c
A message from kapa.ai
Yes, running the Ory CLI Proxy could help in this situation. The Ory CLI Proxy is a reverse proxy that rewrites cookies to match the domain your application is currently on. It mirrors Ory endpoints on the same domain as the application you're running and rewrites cookies to match the domain your application is currently on. This behavior is necessary to avoid issues with the browser CORS policy. By using the Proxy, you can easily connect the application you're developing locally to Ory Network and consume the APIs without additional configuration or self-hosting any Ory services. Here's how you can install the Ory CLI Proxy:
Copy code
bash npm i --save @ory/cli
And here's how you can use it:
Copy code
bash ory proxy <http://localhost:3000> <https://my-domain.com>
In this command, replace
<http://localhost:3000>
with the address of your local server, and
<https://my-domain.com>
with the domain where you want to expose the app through the Ory Proxy. Please note that the Ory CLI Proxy should never be the main entry point to your application. Always run an ingress proxy such as Nginx or Traefik in front. (Source: [Ory Documentation](https://www.ory.sh/docs/getting-started/integrate-auth/expressjs#install-ory-cli), [Ory Documentation](https://www.ory.sh/docs/guides/cli/proxy-and-tunnel#use-ory-proxy-when-self-hosting))
s
@chilly-king-10285 but I don’t need it for this case, it’s giving me unauthorized for a different reason
c
A message from kapa.ai
If you're receiving a 401 Unauthorized error, it could be due to a few reasons: 1. The session token is not valid: Ensure that the session token you're using is valid and has not expired. You can check the validity of a session token using the
ToSession
method in the Ory SDK. 2. The session token is not being sent correctly: Ensure that the session token is being sent in the
Authorization
header of your requests, and that it's being prefixed with
Bearer
. 3. Anti-Cross-Site Request Forgery (CSRF) mechanisms are triggered: Ory uses CSRF mechanisms to protect against CSRF attacks. If you're getting 401 Unauthorized responses, it could be because these mechanisms are being triggered. You can debug issues related to cookies or anti-CSRF defenses using tools like the Chrome DevTools. If you're still having issues, it might be helpful to look at the server logs to see if there are any error messages that could give you more information about why the requests are being unauthorized. (Source: [Ory Documentation](https://www.ory.sh/docs/troubleshooting/csrf), [Ory Documentation](https://www.ory.sh/docs/cli/ory#ory))
s
@chilly-king-10285 great thank you. Can the frontend flow have the user login through the browser, and then return the session token for the cli w/ a redirect?
c
A message from kapa.ai
Yes, you can implement a flow where the user logs in through the browser and then the session token is returned to the CLI. However, this would require some additional steps: 1. The user initiates the login process in the CLI, which then opens a browser window for the user to log in. 2. After successful login, Ory will issue a session cookie (for browser clients) and redirect the user to a specified URL. This is where you can implement a custom server-side logic to exchange the session cookie for a session token. 3. Your server-side application can make a request to the
/sessions/whoami
endpoint with the session cookie to get the session payload. 4. Once you have the session payload, you can generate a session token from it and return this token to the CLI. Here's an example of how you might check the current session using a session cookie in Go:
Copy code
go import (  "<http://github.com/ory/client-go|github.com/ory/client-go>"  "<http://github.com/ory/client-go/models|github.com/ory/client-go/models>" )  func getSessionFromCookie(cookie string) (*models.Session, error) {  client := client.NewHTTPClientWithConfig(nil, &client.TransportConfig{   Host:     "<https://playground.projects.oryapis.com>",   BasePath: "/",   Schemes:  []string{"https"},  })   params := client.NewToSessionParams()  params.HTTPClient = &http.Client{}  params.SetHTTPClient(params.HTTPClient)  params.HTTPClient.Transport = &transformCookieTransport{   originalTransport: params.HTTPClient.Transport,   cookie:            cookie,  }   session, err := client.FrontendApi.ToSession(params.Context()).Execute()  if err != nil {   return nil, err  }   return session.Payload, nil }
In this example, replace
"<https://playground.projects.oryapis.com>"
with your Ory server URL, and
cookie
with the actual session cookie. Please note that this is a simplified example and you might need to adjust it to fit your specific use case. (Source: [Ory Documentation](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-cookie))
s
@chilly-king-10285 is the cookie here the same as the session token?
c
A message from kapa.ai
No, the session cookie and the session token are not the same, but they serve a similar purpose. Both are used to maintain user sessions, but they are used in different contexts. - Session Cookie: This is issued when a user signs in through a browser-based login flow. The session cookie is stored in the user's browser and sent with each subsequent request to the server. This allows the user to remain authenticated without having to sign in again for each request. - Session Token: This is issued when a user signs in through a client other than a web browser, such as a native mobile app or a CLI application. The session token is sent in the
Authorization
header of each subsequent request to the server. In both cases, the session cookie or token is proof that the user is authenticated and allows them to interact with the system without the need to re-authenticate for every request. (Source: [Ory Documentation](https://www.ory.sh/docs/kratos/session-management/overview))
s
@chilly-king-10285 so how do I swap between a session cookie and a session token when I have the user login via browser?
c
A message from kapa.ai
To swap between a session cookie and a session token, you would need to implement a server-side component that can make a request to the
/sessions/whoami
endpoint with the session cookie, and then generate a session token from the returned session payload. Here's a high-level overview of the process: 1. The user logs in through the browser, and Ory issues a session cookie. 2. Your server-side application makes a request to the
/sessions/whoami
endpoint with the session cookie. This can be done using the Ory SDK or directly with an HTTP client. 3. The
/sessions/whoami
endpoint returns the session payload, which includes the session ID, the identity of the authenticated user, and other session information. 4. Your server-side application generates a session token from the session payload. This could be done by encoding the session payload as a JSON Web Token (JWT), for example. 5. Your server-side application returns the session token to the CLI. Here's an example of how you might check the current session using a session cookie in Go:
Copy code
go import (  "<http://github.com/ory/client-go|github.com/ory/client-go>"  "<http://github.com/ory/client-go/models|github.com/ory/client-go/models>" )  func getSessionFromCookie(cookie string) (*models.Session, error) {  client := client.NewHTTPClientWithConfig(nil, &client.TransportConfig{   Host:     "<https://playground.projects.oryapis.com>",   BasePath: "/",   Schemes:  []string{"https"},  })   params := client.NewToSessionParams()  params.HTTPClient = &http.Client{}  params.SetHTTPClient(params.HTTPClient)  params.HTTPClient.Transport = &transformCookieTransport{   originalTransport: params.HTTPClient.Transport,   cookie:            cookie,  }   session, err := client.FrontendApi.ToSession(params.Context()).Execute()  if err != nil {   return nil, err  }   return session.Payload, nil }
In this example, replace
"<https://playground.projects.oryapis.com>"
with your Ory server URL, and
cookie
with the actual session cookie. Please note that this is a simplified example and you might need to adjust it to fit your specific use case. (Source: [Ory Documentation](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-cookie))