Using JWT (Json Web Token) for API-based user authentication in Laravel 5

Source: Internet
Author: User
Tags compact
Today in JavaScript's front-end technology, we typically only need to build APIs in the background to provide front-end calls, and the backend is only designed to be called to the front-end mobile app. User authentication is an important part of WEB applications, and API-based user authentication has two best Solutions--oauth 2.0 and JWT (JSON Web Token).

1. JWT definition and its composition

The JWT (JSON Web Token) is a very lightweight specification. This specification allows us to use JWT to deliver secure and reliable information between the user and the server.

A JWT is actually a string that consists of three parts, the head, the payload, and the signature.

load (Payload)

We will first describe the user-authenticated operation as a JSON object. Some additional information was added to help understand the JWT for future servers receiving this JWT.

{    "sub": "1",    "ISS": "Http://localhost:8000/auth/login",    "IAT": 1451888119,    "exp": 1454516119,    "NBF": 1451888119,    "JTI": "37c107e4609ddbcc9c096ea5ee76c667"}

The first 6 fields are defined by the JWT standard.

    • Sub: The user to which the JWT is intended
    • ISS: The issuer of the JWT
    • IAT (issued at): When to issue tokens
    • EXP (expires): When does token expire
    • NBF (not before): Token cannot be received before this time is processed
    • JTI:JWT ID provides a unique identifier for Web token

These definitions can be found in the standard.

The above JSON object is Base64 encoded to get the following string:

Eyjzdwiioiixiiwiaxnzijoiahr0cdpcl1wvbg9jywxob3n0ojgwmdfcl2f1dghcl2xvz2luiiwiawf0ijoxnduxodg4mte5lcjlehaioje0ntq1mtyxmtksi M5izii6mtq1mtg4odexoswianrpijoimzdjmta3ztq2mdlkzgjjyzljmdk2zwe1zwu3nmm2njcifq

This string we call it the payload (load) of the JWT.

If you use node. js, you can use the node. js package Base64url to get this string:

var Base64url = require (' Base64url ') var header = {    "From_user": "B",    "Target_user": "A"}console.log (Base64url ( Json.stringify (header)))

Note: Base64 is an encoding, that is, it can be translated back to the original appearance. It is not a cryptographic process.

Head (header)

JWT also requires a head, which is used to describe the most basic information about the JWT, such as its type and the algorithm used to sign it. This can also be represented as a JSON object:

{  "Typ": "JWT",  "ALG": "HS256"}

Here we show that this is a JWT, and the signature algorithm we use (which is mentioned later) is the HS256 algorithm.

It also has to be Base64 encoded, and then the string becomes the header of the JWT (head):

Eyj0exaioijkv1qilcjhbgcioijiuzi1nij9

signature (signature)

Use a period for the two encoded strings above. Connected together (head in front), formed:

Eyj0exaioijkv1qilcjhbgcioijiuzi1nij9.eyjzdwiioiixiiwiaxnzijoiahr0cdpcl1wvbg9jywxob3n0ojgwmdfcl2f1dghcl2xvz2luiiwiawf0ijox Nduxodg4mte5lcjlehaioje0ntq1mtyxmtksim5izii6mtq1mtg4odexoswianrpijoimzdjmta3ztq2mdlkzgjjyzljmdk2zwe1zwu3nmm2njcifq

Finally, we encrypt the string above the concatenation with the HS256 algorithm. At the time of encryption, we also need to provide a key (secret):

HMACSHA256 (    Base64urlencode (header) + "." +    Base64urlencode (payload),    secret)

This will give us the encrypted content:

Wyoq95rjayq2ff3aj8evcsaumep0kuqccjdennfnat4

This part is also called signature.

Finally, this part of the signature is also stitched behind the signed string, and we get the full JWT:

Eyj0exaioijkv1qilcjhbgcioijiuzi1nij9.eyjzdwiioiixiiwiaxnzijoiahr0cdpcl1wvbg9jywxob3n0ojgwmdfcl2f1dghcl2xvz2luiiwiawf0ijox Nduxodg4mte5lcjlehaioje0ntq1mtyxmtksim5izii6mtq1mtg4odexoswianrpijoimzdjmta3ztq2mdlkzgjjyzljmdk2zwe1zwu3nmm2njcifq.wyoq95 Rjayq2ff3aj8evcsaumep0kuqccjdennfnat4

2. Integrated JWT to Laravel 5

installation

We install the JWT expansion pack using composer:

Composer require Tymon/jwt-auth 0.5.*

Configuration

After the installation is complete, you need to register the appropriate service provider in config/app.php:

Tymon\jwtauth\providers\jwtauthserviceprovider::class

Then register the corresponding façade to be used:

' Jwtauth ' = Tymon\jwtauth\facades\jwtauth::class ' jwtfactory ' and Tymon\jwtauth\facades\jwtfactory::class

Then publish the appropriate configuration file:

PHP artisan vendor:publish--provider= "Tymon\jwtauth\providers\jwtauthserviceprovider"

Finally generate the key:

PHP Artisan Jwt:generate

If you want to add it to an. env file, create the Jwt_secret field in. env and execute the command that generated the key again.

In config/jwt.php, you can configure the following options:

    • Ttl:token validity period (minutes)
    • Refresh_ttl: Refresh token time (minutes)
    • Algo:token Signature Algorithm
    • User: The namespace path to the user model
    • Identifier: Used to get a user from a sub in token
    • Require_claims: The option must appear in token's payload, otherwise the tokeninvalidexception exception will be thrown
    • blacklist_enabled: If this option is set to False, then we will not be able to revoke token, even if we refresh token, the previous token is still valid
    • Providers: Complete the specific implementation of various tasks, you can rewrite them if necessary
      • User--providers.user: Obtaining a user's implementation based on sub
      • JWT--PROVIDERS.JWT: Encrypt/Decrypt Tokens
      • Authentication--providers.auth: Obtaining Authenticated Users through certificate/id
      • Storage--providers.storage: Store tokens until they expire

Create token

The most common way to create a user token is by logging in to achieve user authentication, and if successful, returns the token of the appropriate user. This assumes that we have a authenticatecontroller:

Use Jwtauth;use tymon\jwtauth\exceptions\jwtexception;class Authenticatecontroller extends Controller{public    Function authenticate (Request $request)    {        //grab credentials from the Request        $credentials = $request Only (' email ', ' password ');        try {            //attempt to verify the credentials and create a tokens for the user            if (! $token = Jwtauth::attempt ($creden Tials) {                return response ()->json ([' error ' = ' = ' invalid_credentials '], 401);            }        } catch (jwtexception $e) {            //something went wrong whilst attempting to encode the token            return response ()->json ([' Error ' = ' C ' Ould_not_create_token '], ();        }        All good so return the token        return response ()->json (Compact (' token '));}    }

Sometimes we can also create tokens directly from user object instances:

Grab some user$user = User::first (); $token = Jwtauth::fromuser ($user);

In addition, you can use Tymon\jwtauth\payloadfactory instances (or jwtfactory facades) to create tokens based on arbitrary data:

$customClaims = [' foo ' = ' bar ', ' baz ' = ' bob ']; $payload = Jwtfactory::make ($customClaims); $token = Jwtauth::encod E ($payload);

You can also use the method chain as follows:

Add a custom claim with a key of ' Foo ' and a value of [' Bar ' = ' baz '] $payload = jwtfactory::sub (123)->aud (' foo ') ->foo ([' Bar ' = ' baz '])->make (); $token = Jwtauth::encode ($payload);

user authentication

After the user has successfully logged in, the next step is to send a token-containing request to obtain the user information.

To send a request that requires authentication via HTTP, you need to set the authorization header:

Authorization:bearer {Yourtokenhere}

If the username/password is not base64 encoded then Apache seems to abandon the authorization header, to fix this problem you can add the following code to the Apache configuration file:

Rewriteengine Onrewritecond%{http:authorization} ^ (. *) rewriterule. *-[e=http_authorization:%1]

Or include the token information in the URL:

Http://api.mysite.com/me?token={yourtokenhere}

To get tokens from a request, you can do this:

This would set the token on the Objectjwtauth::p arsetoken ();//And you can continue to chain Methods$user = Jwtauth::p ar Setoken ()->authenticate ();

To get the token value, you can call this:

$token = Jwtauth::gettoken ();

If token is set, it will be returned, otherwise it will attempt to parse token from the request using the method if token is not set or cannot be resolved and the final return is false.

Of course, you can also set tokens manually if needed:

Jwtauth::settoken (' Foo.bar.baz ');

Get Authenticated Users from token:

//somewhere in your controllerpublic function Getauthenticateduser () {try {if (! $user = Jwtauth::p arsetoken ()->authenticate ())        {return response ()->json ([' User_not_found '], 404); }} catch (Tymon\jwtauth\exceptions\tokenexpiredexception $e) {return response ()->json ([' token_expired '], $e    ->getstatuscode ()); } catch (Tymon\jwtauth\exceptions\tokeninvalidexception $e) {return response ()->json ([' Token_invalid '], $e-    Getstatuscode ()); } catch (Tymon\jwtauth\exceptions\jwtexception $e) {return response ()->json ([' token_absent '], $e->GETSTATUSC    Ode ()); }//The token is valid and we have found the user via the sub claim Return response ()->json (compact (' user ')); 

The Jwt-auth extension also provides two middleware Getuserfromtoken and Refreshtoken, which are used to check if tokens are included in the request header and parameters, and attempt to decode them, which again resolves tokens from the request. and sequentially refreshes the token (discarding the old token at the same time) and takes it as part of the next response. To use these two middleware, you need to register them in the $routeMiddleware attribute under app/http/kernel.php:

protected $routeMiddleware = [    ...    ' Jwt.auth ' = ' tymon\jwtauth\middleware\getuserfromtoken ',    ' jwt.refresh ' = ' tymon\jwtauth\middleware\ Refreshtoken ',];

JWT makes user authentication simple and secure, tokens are saved to local storage/web or cookies, and using JWT, API-based user authentication is no longer difficult.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.