Last active
October 21, 2021 21:27
-
-
Save sahilkashyap64/89e1a7d5d6114656cdac7f4a889aa823 to your computer and use it in GitHub Desktop.
Ratchet websocket qr login like whatsapp laravel ,cboden/ratchet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use App\Http\Controllers\Controller; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\Auth; | |
class QRLoginTwoController extends Controller | |
{ | |
public function qrtesting() | |
{ | |
return view('frontend.qrtesting'); | |
} | |
public function qrscanner2() | |
{ | |
if (Auth::check()) | |
{ | |
$login = true; | |
return view('frontend.qrscanner2', compact('login')); | |
} | |
return redirect()->route('home'); | |
} | |
public function loginWS(Request $request) | |
{ | |
$key = $request['key']; | |
if (empty($key)) | |
{ | |
$return = array( | |
'status' => 2, | |
'msg' => 'key not provided' | |
); | |
return response()->json($return, 200); | |
} | |
$userid = UnHashUserID($key); | |
try | |
{ | |
$user = Auth::loginUsingId($userid, true); | |
$return = array( | |
'status' => 1, | |
'msg' => 'success', | |
'jwt' => 1, | |
'user' => $user | |
); | |
return response()->json($return, 200); | |
} | |
catch(Exception $exception) | |
{ | |
return response()->json(['status' => 2, 'success' => false, 'message' => 'Some Error occured', 'error' => $exception->getMessage() , 'response_code' => 200, | |
], 200); | |
} | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> | |
<script src="{{ asset('frontend/qr/jquery.qrcode-0.11.0.min.js') }}" ></script> | |
@section('content') | |
@if(session()->has('message')) | |
<div class="alert alert-success alert-dismissible "> | |
<button type="button" class="close" data-dismiss="alert">×</button> | |
{{ session()->get('message') }} | |
</div> | |
@endif | |
@include('frontend.partials.sidenavRegisterAndLogin') | |
<section class="page-section"> | |
<div class="container"> | |
<h2 class="section-heading text-center">QR code scanner</h2> | |
<div class="row setting-cards"> | |
<div class="col-centered col-md-8"> | |
<ul class="setting-card"> | |
<li class="text-center"> | |
<?php $hashedid= HashUserID(Auth::user()->id); ?> | |
<p>passcode: {{$hashedid}}</p> | |
<p>Name: {{Auth::user()->name}}</p> | |
<p>Email: {{Auth::user()->email}}</p> | |
</li> | |
<li class="text-center"> | |
<div id="qr-reader" class="col-md-8"></div> | |
<p id="login_mobile_scan_qrcode"></p> | |
<p id="qrcodedoLogin"></p></li> | |
</ul> | |
<div id="qr-reader-results"></div> | |
</div> | |
</div> | |
@if ($errors->any()) | |
<div class="alert alert-danger"> | |
<ul> | |
@foreach ($errors->all() as $error) | |
<li>{{ $error }}</li> | |
@endforeach | |
</ul> | |
</div> | |
@endif | |
</div> | |
</section><section class="page-section"> | |
</section> | |
@endsection | |
</body> | |
<script src="{{ asset('frontend/qr/html5-qrcode.min.js') }}" ></script> | |
<script> | |
function qrcodedoLogin(param){ | |
var url = param; | |
console.log("qrcodedoLogin called",url); | |
$.ajax({ | |
type: "POST" , | |
dataType: "json" , | |
url: url , | |
data:{ | |
//key:key | |
}, | |
success:function(data) { | |
if (data.status==1 ){ | |
var qrcodeloginurl = data.msg; | |
//scan successfull url recieved | |
$('#qrcodedoLogin').text("QR Loggin successfully"); | |
// console.log("qrcodeloginurl",qrcodeloginurl); | |
//qrcodedoLogin(qrcodeloginurl); | |
} else if (data.status==2 ){ | |
//couldn't do login | |
// alert(data.msg); | |
$('#qrcodedoLogin').text(data.msg); | |
} | |
} | |
}); | |
} | |
function login_mobile_scan_qrcode(param){ | |
var url = param; | |
if ("WebSocket" in window) { | |
var base = window.location.hostname; | |
var ws = new WebSocket('wss://'+base+':8090'); | |
ws.onopen = function() { | |
console.log("on WS open we sent the token to server"); | |
let params = (new URL(url)).searchParams; | |
let urltoken = params.get('t'); | |
ws.send(JSON.stringify({ type: "client", step: 0, token: urltoken })); | |
}; | |
ws.onmessage = function(event) { | |
const data = JSON.parse(event.data); | |
console.log(" client body",data); | |
const step = data.data && data.data.step; | |
if (step === 0) { | |
console.log("step",step); | |
}else if (step === 1) { | |
ws.send(JSON.stringify({ type: "client", step: 1, username:'{{$hashedid}}' })); | |
} | |
} | |
ws.onclose = function() { | |
console.log("Connection is closed..."); | |
}; | |
} else { | |
alert("WebSocket NOT supported by your Browser!"); | |
} | |
// console.log("login_mobile_scan_qrcode called",url); | |
} | |
function docReady(fn) { | |
// see if DOM is already available | |
if (document.readyState === "complete" | |
|| document.readyState === "interactive") { | |
// call on next available tick | |
setTimeout(fn, 1); | |
} else { | |
document.addEventListener("DOMContentLoaded", fn); | |
} | |
} | |
docReady(function () { | |
var resultContainer = document.getElementById('qr-reader-results'); | |
var lastResult, countResults = 0; | |
function onScanSuccess(decodedText, decodedResult) { | |
if (decodedText !== lastResult) { | |
++countResults; | |
lastResult = decodedText; | |
// Handle on success condition with the decoded message. | |
console.log(`Scan result ${decodedText}`, decodedResult); | |
resultContainer.innerHTML += `<div>[${countResults}] - ${decodedText}</div>`; | |
login_mobile_scan_qrcode(decodedText); | |
// Optional: To close the QR code scannign after the result is found | |
// html5QrcodeScanner.clear(); | |
} | |
} | |
var html5QrcodeScanner = new Html5QrcodeScanner( | |
"qr-reader", { fps: 10, qrbox: 250 }); | |
html5QrcodeScanner.render(onScanSuccess); | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> | |
<script src="{{ asset('frontend/qr/jquery.qrcode-0.11.0.min.js') }}" ></script> | |
<script type="text/javascript"> | |
$(document).ready(function() { | |
initiate(); | |
}); | |
function initiate() { | |
if ("WebSocket" in window) { | |
var base = window.location.hostname; | |
// var ws = new WebSocket('wss://'+base+':8090'); | |
var ws = new WebSocket('wss://'+base+':8090'); | |
console.log(ws); | |
ws.onopen = function() { | |
ws.send(JSON.stringify({ type: "server", code: 0, step: 0 })); | |
}; | |
ws.onmessage = function(evt) { | |
const data = JSON.parse(event.data); | |
//console.log("datafromservver",data); | |
const step = data.data && data.data.step; | |
if (step === 0) { | |
//Generate QR Code and show to user. | |
$("#qrcode").qrcode({ | |
"width": 100, | |
"height": 100, | |
"text": data.data.url | |
}); | |
console.log("QR code generated successfully"); | |
} else if (step === 2) { | |
const { username, token } = data.data; | |
//localStorage.setItem(TOKEN_KEY, token); | |
$("#qrcode").html(""); | |
ws.close(); | |
//alert(username); | |
is_loginfun(username); | |
} | |
}; | |
ws.onclose = function() { | |
console.log("Connection is closed..."); | |
}; | |
} else { | |
alert("WebSocket NOT supported by your Browser!"); | |
} | |
} | |
// Check whether the login has been confirmed | |
function is_loginfun(param){ | |
var key = param; | |
console.log("is_login called"); | |
$.ajax({ | |
type: "POST" , | |
dataType: "json" , | |
url: "web/loginws" , | |
data:{ | |
key:key , | |
"_token":"{{ csrf_token() }}" | |
}, | |
headers: {'x-csrf-token': '{{ csrf_token() }}'}, | |
success:function(data) { | |
if (data.status==1 ){ | |
var uid = data.jwt; | |
var user = data.user; | |
console.log("user",user); | |
console.log("login successfull",uid); | |
alert("login successfull",uid); | |
window.location.href = '/'; | |
} else if (data.status==2 ){ | |
alert(data.msg); | |
} | |
} | |
}); | |
} | |
</script> | |
<body> | |
<br> | |
<br> | |
<div align="center"> | |
<div id="qrcode"> | |
<img src='iconLoading.gif' /> | |
</div> | |
<div id="profile"></div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
Route::get('/qrtesting', 'Admin\QRLoginTwoController@qrtesting'); | |
Route::post('web/loginws', 'Admin\QRLoginTwoController@loginWS'); | |
Route::get('/qrscanner', 'Admin\QRLoginTwoController@qrscanner2'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Illuminate\Support\Str; | |
use Ratchet\MessageComponentInterface; | |
use Ratchet\ConnectionInterface; | |
class WebSocketController extends Controller implements MessageComponentInterface{ | |
private $connections = []; | |
private $clients; | |
private $cache; | |
public function __construct() | |
{ | |
$this->clients = new \SplObjectStorage(); | |
// memory cache | |
$this->cache = array(); | |
} | |
public function multicast($msg) { | |
foreach ($this->clients as $client) $client->send($msg); | |
} | |
public function send_to($to,$msg) { | |
if (array_key_exists($to, $this->clientids)) $this->clientids[$to]->send($msg); | |
} | |
/** | |
* When a new connection is opened it will be passed to this method | |
* @param ConnectionInterface $conn The socket/connection that just connected to your application | |
* @throws \Exception | |
*/ | |
function onOpen(ConnectionInterface $conn){ | |
$this->clients->attach($conn); | |
echo "New connection! ({$conn->resourceId})\n"; | |
} | |
/** | |
* This is called before or after a socket is closed (depends on how it's closed). SendMessage to $conn will not result in an error if it has already been closed. | |
* @param ConnectionInterface $conn The socket/connection that is closing/closed | |
* @throws \Exception | |
*/ | |
function onClose(ConnectionInterface $conn){ | |
unset($this->cache[$conn->resourceId]); | |
$this->clients->detach($conn); | |
echo "Connection {$conn->resourceId} has disconnected\n"; | |
$this->clients->detach($conn); | |
} | |
/** | |
* If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown, | |
* the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method | |
* @param ConnectionInterface $conn | |
* @param \Exception $e | |
* @throws \Exception | |
*/ | |
function onError(ConnectionInterface $conn, \Exception $e){ | |
echo "An error has occurred: {$e->getMessage()}\n"; | |
$conn->close(); | |
} | |
/** | |
* Triggered when a client sends data through the socket | |
* @param \Ratchet\ConnectionInterface $conn The socket/connection that sent the message to your application | |
* @param string $msg The message received | |
* @throws \Exception | |
*/ | |
function onMessage(ConnectionInterface $from, $msg){ | |
$numRecv = count($this->clients) - 1; | |
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n" | |
, $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); | |
$obj = json_decode($msg); | |
$type = $obj->type; | |
if($type=='client'){ | |
switch ($obj->step) { | |
case 0: | |
// echo "\n inside client,step0 \n"; | |
$token = $obj->token; | |
$theuuid = UnHashUserID($token); | |
//todo add jwt with 2minutes of token | |
$tokenexist=array_key_exists($theuuid, $this->cache); | |
if($tokenexist){ | |
echo "\n token exist ya \n"; | |
$ee=$this->cache[$theuuid]; | |
// print_r($ee); | |
if($ee['status']=='0'){ | |
$this->cache[$theuuid]['status'] = 1; | |
$this->cache[$theuuid] += ['child' => $from]; | |
$myArray2[] = (object) ['step' => 1]; | |
$Scan = new \SplObjectStorage(); | |
$Scan->code=0; | |
$Scan->data=$myArray2[0]; | |
$Scan->msg="Scan code successfully"; | |
$this->cache[$theuuid]['parent']->send(json_encode($Scan)); | |
$ready2 = new \SplObjectStorage(); | |
$ready2->code=0; | |
$ready2->data=$myArray2[0]; | |
$ready2->msg="Ready"; | |
$from->send(json_encode($ready2)); | |
}; | |
}else{ | |
echo "token doesn't exsit"; | |
} | |
break; | |
case 1: | |
$myArray3[] = (object) ['step' => 2]; | |
$myArray4[] = (object) ['step' => 2,'username'=>$obj->username]; | |
foreach ($this->cache as $v) { | |
if($v['child']==$from){ | |
// $token updateSessionToken; | |
$ready3 = new \SplObjectStorage(); | |
$ready3->code=0; | |
$ready3->data=$myArray4[0]; | |
$ready3->msg="Already logged in"; | |
if(array_key_exists("parent", $v)){} | |
$v['parent']->send(json_encode($ready3)); | |
} | |
} | |
$ready = new \SplObjectStorage(); | |
$ready->code=0; | |
$ready->data=$myArray3[0]; | |
$ready->msg="Login successful"; | |
$from->send(json_encode($ready)); | |
} | |
}else if($type=='server'){ | |
// echo "hello inside server"; | |
//to get the QR logo | |
switch ($obj->step) { | |
case 0: | |
$uuid = $from->resourceId;//Str::random(30); | |
echo $uuid; | |
$token = HashUserID($uuid); | |
// echo $token; | |
$this->cache[$uuid] = [ 'status'=> 0, 'parent'=> $from ]; | |
$url = url(''); // Get the current url | |
// dd($url); | |
$http = $url .'?t='.$token; // Verify the url method of scanning code | |
$myArray[] = (object) ['step' => 0,'url' => $http]; | |
$ready = new \SplObjectStorage(); | |
$ready->code=0; | |
$ready->data=$myArray[0]; | |
$ready->msg="Ready"; | |
$from->send(json_encode($ready)); | |
break; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
use Ratchet\Server\IoServer; | |
use Ratchet\Http\HttpServer; | |
use Ratchet\WebSocket\WsServer; | |
use App\Http\Controllers\WebSocketController; | |
use React\EventLoop\Factory; | |
use React\Socket\SecureServer; | |
use React\Socket\Server; | |
class WebSocketServer extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'websocket:init'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Initializing Websocket server to receive and manage connections'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ //for local | |
// $this->forlocal(); | |
//for prod server | |
$this->forprodserver(); | |
} | |
public function forlocal() | |
{ | |
$server = IoServer::factory(new HttpServer(new WsServer(new WebSocketController())) , 8090); | |
$server->run(); | |
} | |
public function forprodserver() | |
{ | |
$loop = Factory::create(); | |
$webSock = new SecureServer(new Server('0.0.0.0:8090', $loop) , $loop, array( | |
'local_cert' => '/etc/letsencrypt/live/streamlytest.streamlytv.com/fullchain.pem', // path to your cert | |
'local_pk' => '/etc/letsencrypt/live/streamlytest.streamlytv.com/privkey.pem', // path to your server private key | |
'allow_self_signed' => true, // Allow self signed certs (should be false in production) | |
'verify_peer' => false | |
)); | |
// Ratchet magic | |
$webServer = new IoServer(new HttpServer(new WsServer(new WebSocketController())) , $webSock); | |
$loop->run(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment