Baasic Membership REST API

In this series of blog posts we’re going to cover technical details and some internals of the Baasic membership system. We’ll start with explaining how user authentication works via login endpoint.

Membership endpoints

Baasic membership system has 4 main sections:

  • login: responsible for authenticating users and managing tokens.
  • users: responsible for managing users in your applications.
    • register: a specialized endpoint allowing users to register in your applications.
    • recover-password: a specialized endpoint allowing users to recover forgotten passwords.
  • roles: responsible for managing roles in your applications.
  • permissions: responsible for managing access rights for various REST API endpoints.

Login

Login is an endpoint that is used for user authentication; in other words it is responsible for creating and managing user access tokens. Once an access token is acquired, it can be used to access protected resources. In order to get an access token, we need to supply the username and password of the user to the login endpoint using HTTP POST method.

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username={username}&password={password}&grant_type=password" https://api.baasic.com/<version>/<api-key>/login

One important thing to note here is that the data you are sending must be in x-www-form-urlencoded format. If credentials we’ve just sent are correct, we should get a response similar to this:

{"access_token":"[YOUR_ACCESS_TOKEN]","token_type":"bearer","expires_in":7200}

token_type tells us the type of token (it will always be “bearer” in Baasic), expires_in tells us how for long (in seconds) this token is valid, while access_token is the token you’re going to use to access protected resources - we’ll soon see how.

Access token contains information about user associated with token and token type. This information is signed and encrypted to prevent malicious users to easily forge access tokens. If you send incorrect credentials, you should get 400 BAD REQUEST with details why request failed. For more details about errors, you should check here.

There are two optional parameters you can use when creating token. They will change default token behavior and both have specific purpose. You can append them to the options parameter:

https://api.baasic.com/<version>/<api-key>/login?options=session,sliding

First option is using a session with token. This option - together with token login endpoint - will set a session cookie associated with this token. It provides an additional layer of security for your calls. You need to send both token and session cookie with each request. This option is mainly useful in browser and similar clients - where storing token securely is not possible, and clients handle cookie automatically. On its own, the cookie has no value and is ignored if there is no token sent with it, but it can serve as an efficient protection from CSRF attacks. In case attacker gets a token using XSS, the attack token will be useless to him as he can’t retrieve session cookies using the same technique. You should avoid using this option in all other cases, as it adds additional complexity without too many benefits.

Second option is to set token expiration to “sliding”. With this option, each successful request will slide token expiration. Successful request in this context is not just one with 2xx response code, but any response returned from the endpoint you accessed - including 4xx and 3xx responses. However, 5xx response will not slide token expiration time. In case of sliding token, instead of expires_in value, you will get sliding_window value you can use to approximately calculate when token should expire.

Once you have acquired access token, you can start making authenticated request by sending token in AUTHORIZATION header for each request:

AUTHORIZATION: bearer [YOUR_ACCESS_TOKEN]

At any point you can invalidate token using the DELETE method

curl -X DELETE -H "Authorization: bearer [YOUR_ACCESS_TOKEN]" -H "Content-Type: application/json" -d '{
"token": "[TOKEN_TO_INVALIDATE]",
"type": "bearer"
}' https://api.baasic.com/<version>/{apikey}/login

You can only invalidate tokens belonging to the user that “owns” the token used to authorize request.

Tokens can be refreshed by using the PUT method:

curl -X PUT -H "Authorization: bearer [YOUR_ACCESS_TOKEN]" -H "Content-Type: application/json" -d '{
"token": "[TOKEN_TO_REFRESH]",
"type": "bearer"
}' https://api.baasic.com/<version>/<api-key>/login

This should return your new token with the same options and invalidate the “old” token you’re refreshing. You will get same response as when you use POST method. Again, you can only refresh your own tokens.

GET method issued on the same endpoint will provide information about the user a particular token is associated to.

curl -X GET -H "Authorization: bearer [YOUR_ACCESS_TOKEN]" -H "Content-Type: application/json" https://api.baasic.com/beta/{apikey}/login

You should get response similar to this:

{
    "displayName": "user",
    "email": "user@mail.com",
    "permissions": {
        "roles" : ["Read"],
        "users" : ["Read", "Create", "Update", "Delete"],
        "keyValueStore" : ["Read", "Create", "Update", "Delete", "Full"],
        "myResource" : ["Create", "Read", "Update", "Delete", "Full"]
    },
    "roles": [
        "Users",
        "Administrators"
    ],
    "userName": "username",
    "dateCreated": "2015-02-13T14:17:32",
    "dateUpdated": "2015-07-01T12:14:02",
    "id": "CzMbiu148o99pcenYCkK00"
}

This response contains useful information about user who is the owner of the token. This information can be used on the client to display information about users, and also to adjust UI based on user roles and/or permissions.

That’s all for this time. In the next installment of this series we’re going to cover user endpoint, and you’ll see how you users can register, activate their accounts and manage their passwords. We’ll also cover how you can manage users through the Baasic REST API.

Feel free to leave a comment

comments powered by Disqus