Laravel – Authenticate user in NodeJS with socket io using JWT
Today, we am going to show you how to authenticate user node js using JWT and socket io in Laravel 5.3. It is very very important because if you are working with a chat application or messengers system etc with the user then you have to use the JWT token because it is a very safe and secure way.
If we work on chat module with socket io but someone can easily hack our code. At that time we require to check given JWT token is valid or not using
socketio-jwt package of Node.
socketio-jwt package thorough we can simply authentication with user and identify that token is valid or not, and also we can get information of login user from JWT token like user_id, name, email etc as we require.
But you thinking about how we can do this with Laravel. So, you have to just follow the bellow step because of it from scratch.
Step 1: Install Laravel 5 Application
In this step, if you haven’t laravel 5 application setup then we have to get fresh laravel 5 application. So run bellow command and get clean fresh laravel 5.3 application.
composer create-project --prefer-dist laravel/laravel blog
Ok, now go on Laravel application root directory and run bellow command, this commands for make auth and create migration table.
php artisan make:auth
php artisan migrate
Step 2: JWT Package Installation
Here you should know about JWT stands for JSON Web Token. JWT will help to create authentication and connect front-end and back-end functions. JWT through we can create login and register API. So first we have to install “tymon/jwt-auth” package in laravel 5.
We are also installing barryvdh/laravel-cors package for handle Cross-Origin Resource Sharing (CORS).
So, run bellow command and install.
composer require barryvdh/laravel-cors tymon/jwt-auth
After install this package, Now open config/app.php file and add service provider.
config/app.php
'providers' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
Barryvdh\Cors\ServiceProvider::class,
]
.......
After this we have to publish configuration by following command:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"
Ok now, we have to add the CORS middleware to the `app/Http/Kernel.php` global as like bellow:
app/Http/Kernel.php
....
protected $middlewareGroups = [
'web' => [
.......
\Barryvdh\Cors\HandleCors::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
....
Ok, now we have to make more secure JWT token using JWT Secret, so we can set JWT secret on our ‘.env’ file so open env file and put bellow line:
.env
JWT_SECRET=B1Bbr8EnAdJASz3l7Wl0U69f4UHsdtDX
Step 3: Create Token Route
In this is a step we need to create a route of generating JWT token. so open your routes/web.php file and add the following route.
Route::get('token', 'TokenController@token');
Step 4: Create Controller
In this step, now we should create new controller as TokenController in this path app/Http/Controllers/TokenController.php. this controller will return us a token, so put bellow content in controller file:
app/Http/Controllers/TokenController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Facades\JWTAuth;
class TokenController extends Controller
{
public function token(Request $request, \Tymon\JWTAuth\JWTAuth $auth)
{
Auth::loginUsingId($request->id);
$user = Auth::user();
$claims = ['userid' => $user->id, 'email' => $user->email];
$token = $auth->fromUser($user, $claims);
return response()->json(['token' => $token]);
}
}
Step 5: Install Node JS
in this step we will install nodejs if you haven’t installed at. So, make sure you can check if nodejs is not install then you can fire following command and install nodejs easily.
sudo apt-get update
sudo apt-get install nodejs
Step 6: Install npm
we have to also need to install npm because we will install more socket.io, socketio-jwt, and express package using npm command, so if you not installed this command before then install by the following command.
sudo apt-get install npm
Step 7: Install NodeJS Other Packages
In this step we have to require install several package like as bellow:
1) Express
2) Socket.io
3) Dotenv
4) Socketio-jwt
Run bellow command and install above nodejs packages:
npm install express socket.io socketio-jwt dotenv --save
Step 8: NodeJS File(Server Side)
Now we have to create nodejs file, So first go on laravel root directory and create nodejs. and inside that folder create server.js File. Put bellow code on that file:
nodejs/server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var socketioJwt = require('socketio-jwt');
var myEnv = require('dotenv').config({path:'../.env'});
/*
Accept connection and authorize token code
*/
io.on('connection', socketioJwt.authorize({
secret: myEnv.JWT_SECRET,
timeout: 15000
}));
/*
When authenticated, send back userid + email over socket
*/
io.on('authenticated', function (socket) {
console.log(socket.decoded_token);
socket.emit('user-id', socket.decoded_token.userid);
socket.emit('user-email', socket.decoded_token.email);
socket.on('public-my-message', function (data) {
socket.emit('receive-my-message', data.msg);
});
});
/*
Start NodeJS server at port 3000
*/
server.listen(3000);
Step 9: JS File(Client Side)
Ok, in Last step we have to create myauth.html file. In this file i write code for fire Ajax and get token from Laravel and then emit token on nodejs server.
So, put bellow code on that file:
myauth.html
<!doctype html>
<html lang="en">
<head>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.js"></script>
</head>
<body>
<h1>Socket Connection Status: <span id="connection"></span></h1>
<h1>Login User Id: <span id="userid"></span></h1>
<h1>Login User Email: <span id="email"></span></h1>
<h1>Public Message: <span id="receive-my-message"></span></h1>
<script type="text/javascript">
$(document).ready(function () {
socketIOConnectionUpdate('Requesting JWT Token from Laravel');
$.ajax({
url: 'http://localhost:8000/token?id=1'
})
.fail(function (jqXHR, textStatus, errorThrown) {
socketIOConnectionUpdate('Something is wrong on ajax: ' + textStatus);
})
.done(function (result, textStatus, jqXHR) {
/*
make connection with localhost 3000
*/
var socket = io.connect('http://localhost:3000');
/*
connect with socket io
*/
socket.on('connect', function () {
socketIOConnectionUpdate('Connected to SocketIO, Authenticating')
socket.emit('authenticate', {token: result.token});
socket.emit('public-my-message', {'msg': 'Hi, Every One.'});
});
/*
If token authenticated successfully then here will get message
*/
socket.on('authenticated', function () {
socketIOConnectionUpdate('Authenticated');
});
/*
If token unauthorized then here will get message
*/
socket.on('unauthorized', function (data) {
socketIOConnectionUpdate('Unauthorized, error msg: ' + data.message);
});
/*
If disconnect socketio then here will get message
*/
socket.on('disconnect', function () {
socketIOConnectionUpdate('Disconnected');
});
/*
Get Userid by server side emit
*/
socket.on('user-id', function (data) {
$('#userid').html(data);
});
/*
Get Email by server side emit
*/
socket.on('user-email', function (data) {
$('#email').html(data);
});
/*
Get receive my message by server side emit
*/
socket.on('receive-my-message', function (data) {
$('#receive-my-message').html(data);
});
});
});
/*
Function for print connection message
*/
function socketIOConnectionUpdate(str) {
$('#connection').html(str);
}
</script>
</body>
</html>
Ok, Finally we are ready for run but Make sure following point:
1) You must have one user with id = 1 in your users table
2)Â run laravel application by bellow command :
php artisan serve
3)Â run nodejs file by bellow command:
nodejs server
Or
node server
4) run myauth.html file.
That’s IT.
Maybe it can help you….