# Initiate user signup or login

Login initiation begins your authentication flow. You redirect users to Scalekit's hosted login page by creating an authorization URL with appropriate parameters.When users visit this URL, Scalekit's authorization server validates the request, displays the login interface, and handles authentication through your configured connection methods (SSO, social providers, Magic Link or Email OTP

```sh title="Authorization URL format" showLineNumbers=false
<SCALEKIT_ENVIRONMENT_URL>/oauth/authorize?
  response_type=code& # always `code` for authorization code flow
  client_id=<SCALEKIT_CLIENT_ID>& # Dashboard > Developers > Settings > API Credentials
  redirect_uri=<CALLBACK_URL>& # Dashboard > Authentication > Redirect URLs > Allowed Callback URLs
  scope=openid+profile+email+offline_access& # Permissions requested. Include `offline_access` for refresh tokens
  state=<RANDOM_STATE> # prevent CSRF attacks
```

The authorization request includes several parameters that control authentication behavior:

- **Required parameters** ensure Scalekit can identify your application and return the user securely
- **Optional parameters** enable organization routing and pre-populate fields
- **Security parameters** prevent unauthorized access attempts

Understand each parameter and how it controls the authorization flow:

| Query parameter | Description |
|-----------|-------------|
| `response_type` | Set to `code` for authorization code flow Required<br />Indicates the expected response type |
| `client_id` | Your application's public identifier from the dashboard Required<br />Scalekit uses this to identify and validate your application |
| `redirect_uri` | Your application's callback URL where Scalekit returns the authorization code Required<br />Must be registered in your dashboard settings |
| `scope` | Space-separated list of permissions Required<br />Always include `openid profile email`. Add `offline_access` to request refresh tokens for extended sessions |
| `state` | Random string generated by your application Recommended<br />Scalekit returns this unchanged. Use it to prevent CSRF attacks and maintain request state |
| `prompt` | Value to control the authentication flow Recommended<br />Use `login` to force re-authentication<br />Use `create` to trigger sign up page<br />Use `select_account` to select an account if they have multiple accounts |
| `organization_id` | Route user to specific organization's configured authentication method Optional |
| `connection_id` | Skip organization selection and direct user to specific SSO connection Optional |
| `login_hint`| Pre-populate the email field with a hint Optional<br />Useful for domain-based routing when combined with `organization_id` |

## Set up login flow

1. #### Add `state` parameter recommended

   Always generate a cryptographically secure random string for the `state` parameter and store it temporarily (session, local storage, cache, etc).

    This can be used  to validate that the state value returned in the callback matches the original value you sent. This prevents **CSRF (Cross-Site Request Forgery)** attacks where an attacker tricks users into approving unauthorized authentication requests.

    ```javascript title="Generate and store state"
    // Generate secure random state
    const state = require('crypto').randomBytes(32).toString('hex');
    // Store it temporarily (session, local storage, cache, etc)
    sessionStorage.oauthState = state;
    ```
    ```python title="Generate and store state"
    import os
    import secrets

    # Generate secure random state
    state = secrets.token_hex(32)
    # Store it temporarily (session, local storage, cache, etc)
    session['oauth_state'] = state
    ```
    ```go title="Generate and store state"
    import (
        "crypto/rand"
        "encoding/hex"
    )

    // Generate secure random state
    b := make([]byte, 32)
    rand.Read(b)
    state := hex.EncodeToString(b)
    // Store it temporarily (session, local storage, cache, etc)
    // Example for Go: use a storage library
    // session.Set("oauth_state", state)
    ```
    ```java title="Generate and store state"
    import java.security.SecureRandom;
    import java.util.Base64;

    // Generate secure random state
    SecureRandom sr = new SecureRandom();
    byte[] randomBytes = new byte[32];
    sr.nextBytes(randomBytes);
    String state = Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
    // Store it temporarily (session, local storage, cache, etc)
    // Example for Java: use any storage library
    // session.setAttribute("oauth_state", state);
    ```
2. #### Redirect to the authorization URL

    Use the Scalekit SDK to generate the authorization URL. This method constructs the URL locally without making network requests. Redirect users to this URL to start authentication.

    ```javascript title="Express.js" collapse={1-4} {12} ins={9} "getAuthorizationUrl"
    import { Scalekit } from '@scalekit-sdk/node';

    const scalekit = new Scalekit(/* your credentials */);

    // Basic authorization URL for general login
    const redirectUri = 'https://yourapp.com/auth/callback';
    const options = {
      scopes: ['openid', 'profile', 'email', 'offline_access'],
      state: sessionStorage.oauthState,
    };

    const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, options);

    // Redirect user to Scalekit's hosted login page
    res.redirect(authorizationUrl);
    ```
    ```python title="Flask" collapse={1-3} {11} "get_authorization_url"
    from scalekit import ScalekitClient, AuthorizationUrlOptions

    scalekit = ScalekitClient(/* your credentials */)

    # Basic authorization URL for general login
    redirect_uri = 'https://yourapp.com/auth/callback'
    options = AuthorizationUrlOptions(
        scopes=['openid', 'profile', 'email', 'offline_access'],
        state=session['oauth_state'] # Add this line
    )

    authorization_url = scalekit.get_authorization_url(redirect_uri, options)

    # Redirect user to Scalekit's hosted login page
    return redirect(authorization_url)
    ```
    ```go title="Gin" collapse={1-4} {11} "GetAuthorizationUrl"
    import "github.com/scalekit-inc/scalekit-sdk-go"

    scalekit := scalekit.NewScalekitClient(/* your credentials */)

    // Basic authorization URL for general login
    redirectUri := "https://yourapp.com/auth/callback"
    options := scalekit.AuthorizationUrlOptions{
        Scopes: []string{"openid", "profile", "email", "offline_access"},
        State: "your_generated_state", // Add this line
    }

    authorizationUrl, err := scalekitClient.GetAuthorizationUrl(redirectUri, options)

    // Redirect user to Scalekit's hosted login page
    c.Redirect(http.StatusFound, authorizationUrl.String())
    ```
    ```java title="Spring" collapse={1-4} {11} "getAuthorizationUrl"
    import com.scalekit.ScalekitClient;
    import com.scalekit.internal.http.AuthorizationUrlOptions;

    ScalekitClient scalekit = new ScalekitClient(/* your credentials */);

    // Basic authorization URL for general login
    String redirectUri = "https://yourapp.com/auth/callback";
    AuthorizationUrlOptions options = new AuthorizationUrlOptions();
    options.setScopes(Arrays.asList("openid", "profile", "email", "offline_access"));
    options.setState("your_generated_state"); // Add this line

    URL authorizationUrl = scalekit.authentication().getAuthorizationUrl(redirectUri, options);

    // Redirect user to Scalekit's hosted login page
    return new RedirectView(authorizationUrl.toString());
    ```
    Scalekit will try to verify the user's identity and redirect them to your application's callback URL. If the user is a new user, Scalekit will automatically create a new user account.

## Dedicated sign up flow
Cases where your app wants to keep the sign up flow seperate and dedicated to creating the user account, you can use the `prompt: 'create'` parameter to redirect the user to the sign up page.

<RedirectAuthPageSection />

After the user authenticates either in signup or login flows:
1. Scalekit generates an authorization code
2. Makes a callback to your registered allowed callback URL
3. Your backend exchanges the code for tokens by making a server-to-server request

This approach keeps sensitive operations server-side and protects your application's credentials.

Let's take a look at how to complete the login in the next step.