# OAuth Login for User's Tokens

# Security

Please take good care of your OAuth Client id and secret: Client id can be added to the SPAs and mobile apps as that gets used in the redirection urls etc, but use Client secret only in the server to server communications.

If the secret gets leaked to a malicious attacker, they can basically pretend to function as your service, which puts the users' data at risk regarding privacy and monetary issues. If detecting such a situation you must inform Ukko.fi immediately.

# Prerequisites

NOTE This is work in progress so please ask questions and give feedback to us so we can improve the documentation and the API through the Slack channel you've been/will be invited to.

Basic understanding of the OAuth 2. See: https://oauth.net/2/

What we need from you:

  • Redirect urls from your sandbox and production environments. ie https://sandbox.service.com/redirect/ukko. Production info can be delivered later on after the sandbox environment works as intended.

  • Name of your service

  • Short description of your service.

  • PNG logo of your service

  • What features is your service using. Note that changing scopes will require asking the permissions again from the user as the feature scopes are tied to the user's tokens

After these sending these through our Slack as Direct Message to Sami Haapanen and Matias Mäki, we'll generate and send to you OAuth Client ID and Client Secret for your service and the required URLs.

# OAuth Flow

We're using the authorization code flow for login + asking the user if she wants to give permission to handle her data to your service. This provides the user transparency what's happening and explicit control over the usage of her account.

# Authentication

To start the authentication with UKKO.fi for getting the permission and tokens, you'll need to redirect the user to UKKO.fi login portal. Redirection should start with a button which says something like "Integrate your Ukko.fi-account".

Redirect url structure:

https://[UKKO_HOST]/login?client_id=[OAUTH_CLIENT_ID]&redirect_uri=https://[YOUR_SERVICE_REDIRECT_URL]&response_type=code&scope=[YOUR_SCOPES]&state=[STATE_GENERATED_BY_YOU]

Parameters:

HOST: Will be defined later
OAUTH_CLIENT_ID: ie. 12345
YOUR_SERVICE_REDIRECT_URL: 'http://example.com/callback',
YOUR_SCOPES: pat:create,
STATE_GENERATED_BY_YOU: random string generated by your service. You need to verify this later on,

After this you'll get either a:

# Successful login and permission authorization

UKKO.fi redirects user's browser back to your service to YOUR_SERVICE_REDIRECT_URL with following parameters

https://[YOUR_SERVICE_REDIRECT_URL]/?code=[AUTH_CODE]&state=[STATE_GENERATED_BY_YOU]

Verify the [STATE_GENERATED_BY_YOU] with the one your service generated in the beginning to ensure the login is originating from your service.

# Error cases

UKKO.fi redirects user's browser back to your service to YOUR_SERVICE_REDIRECT_URL with following parameters

https://[YOUR_SERVICE_REDIRECT_URL]/?error=access_denied&state=[STATE_GENERATED_BY_YOU]

# Exchanging authorization code to short term OAuth access token

After validating the [STATE_GENERATED_BY_YOU] and getting the [AUTH_CODE] from the redirect. Send HTTP POST form-data request to:

https://[UKKO_HOST]/oauth/token

With the following form parameters:

'grant_type' => 'authorization_code',
'client_id' => [CLIENT_ID],
'client_secret' => [CLIENT_SECRET],
'redirect_uri' => [YOUR_SERVICE_REDIRECT_URL],
'code' => [AUTH_CODE],

Which returns :

{
    "token_type": "Bearer",
    "expires_in": 600,
    "access_token": "token_string..."
    "refresh_token": "token_string..."
}

If you only need short lived token, you can now make new requests with the following headers for the future requests.

Remember to store timestamp now + expires_in, access_token and refresh_token for renewing the expired access_token with the refresh_token.

Accept: 'application/json'
Authorization: 'Bearer [ACCESS_TOKEN]',

If you need to have one long term Personal Access Token for service to service integration with the user's credentials. See the chapter below:

# Creating new long term Personal Access Token for continuous service-to-service integrations

In case your service requires continuous credentials on the behalf of the user, we recommend using long term personal access token. You can request one for the user with the following request:

POST https://[UKKO_HOST]/oauth/personal-access-tokens

HTTP Headers:

    Accept:     'application/json'
    Authorization:  'Bearer [ACCESS_TOKEN]',


JSON  Payload:
{
    name:   "[YOUR_SERVICE_NAME]",
    scopes: ["invoice:create", "invoice:send", "utility"]
}

Returns

{  		
    accessToken: "[LONG_TERM_PAT_STRING]"
    token: {
        id: "id",
        user_id: 123,
        client_id: 123,
        name: [Your Service Name],
        scopes: ["scope 1", "scope 2"],
        revoked: false,
        created_at: "2020-01-21 09:24:37",
        updated_at: "2020-01-21 09:24:37",
        expires_at: "2021-01-20 09:24:37"
    }
}

Store securely the token, scopes and expiry time for the future requests you need to do on the behalf of the user.
The accessToken must be used used as the Bearer token header instead of the short term access token.

After this long term PAT token expires, you must inform the user to ask for the UKKO.fi login and permission again for new PAT.

# Differences between the production and sandbox environments

In production one OAuth client can create only one active PAT token with same scopes. This security limitation is disabled for development sandboxes so integration developers don't have to create new users every time there's need to test this flow.