Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentication with JWT Laravel 5 without password

I'm trying to learn Laravel and my goal is to be able to build a RESTful API (no use of views or blade, only JSON results. Later, an AngularJS web app and a Cordova hybrid mobile app will consume this api.

After some research, I'm inclining to choose JWT-Auth library for completely stateless benefit. My problem is: I have 2 main types of users: customers and moderators. Customers are not required to have a password. I need to be able to generate a token for access with the provided email only. If that email exists in the database and it belongs to a customer, it will generate and return the token. If it exists and belongs to a moderator, it will return false so the interface can request a password. If the email doesn't exist, it throws an invalid parameter error.

I read the docs here and it says it's possible to use Custom Claims. But the docs doesn't explain what are claims and what it means the array being passed as custom claims. I'd like some input on how to go about achieving what I explain above.

    <?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;


class AuthenticateController extends Controller
{

    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        try {
            // verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            // something went wrong
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        // if no errors are encountered we can return a JWT
        return response()->json(compact('token'));
    }
}

Thanks you.

Update

Bounty's code

public function authenticate(Request $request) { 
    $email = $request->input('email');
    $user = User::where('email', '=', $email)->first();
    try { 
        // verify the credentials and create a token for the user
        if (! $token = JWTAuth::fromUser($user)) { 
            return response()->json(['error' => 'invalid_credentials'], 401);
        } 
    } catch (JWTException $e) { 
        // something went wrong 
        return response()->json(['error' => 'could_not_create_token'], 500); 
    } 
    // if no errors are encountered we can return a JWT 
    return response()->json(compact('token')); 
}
like image 293
Marco Aurélio Deleu Avatar asked Oct 09 '15 01:10

Marco Aurélio Deleu


People also ask

How can I use JWT without login?

we don't need a user or login to create JWT, we can generate a token with any kind of data. Simple just generate a token then pass it to the client after that on file convert request verify the token.

Does JWT contain password?

The JWT contains encoded information about the user and a signature that, when decoded, is validated to ensure that the token has not been tampered with. Once the JWT is validated, your application can securely allow the user to generate a new password, instead of sending them their forgotten one.

Does JWT require OAuth?

OAuth is an authorization protocol that can use JWT as a token. OAuth uses server-side and client-side storage. If you want to do real logout you must go with OAuth2. Authentication with JWT token can not logout actually.

How do you Auth with JWT?

To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.


2 Answers

try with this:

$user=User::where('email','=','[email protected]')->first();

if (!$userToken=JWTAuth::fromUser($user)) {
            return response()->json(['error' => 'invalid_credentials'], 401);
        }

return response()->json(compact('userToken'));

it works for me, hope can help

like image 104
Alimjan Avatar answered Oct 08 '22 11:10

Alimjan


Generating token for the customers (without password) can be achieved through

$user = \App\Modules\User\Models\UserModel::whereEmail('[email protected]')->first();
$userToken=JWTAuth::fromUser($user);

Here $userToken will stores the token after existence check of email in the table configured in UserModel file.

I have assumed that you stores both customer and moderators in the same table, there must be some flag to discriminate among them. Assume the flag is user_type

$token = null;
$user = \App\Modules\User\Models\UserModel::whereEmail('[email protected]')->first();
if($user['user_type'] == 'customer'){
   $credentials = $request->only('email');
   $token =JWTAuth::fromUser($user);
}else if($user['user_type'] == 'moderator'){
   $credentials = $request->only('email','password');
   $token = JWTAuth::attempt($credentials);
}else{
   //No such user exists

}
return $token;

As far as custom claims are concerned these are custom defined payloads which can be attached to token string.

For example, JWTAuth::attempt($credentials,['role'=>1]); Will attempt to add role object to token payload. Once you decode the token string through JWT Facade JWTAuth::parseToken()->getPayload(); you in turn get all payloads defined in required_claims under config/jwt.php with additional role payload.

Refer https://github.com/tymondesigns/jwt-auth/wiki/Creating-Tokens#creating-a-token-based-on-anything-you-like Let me know in case you requires anything else.

like image 41
Ashu Jha Avatar answered Oct 08 '22 11:10

Ashu Jha