I know I'll lose the purpose if I store jwt token in my database but for some reason, i want to store it, how can I do that?
Controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Tymon\JWTAuth\JWTAuth;
class AuthController extends Controller
{
/**
* #var \Tymon\JWTAuth\JWTAuth
*/
protected $jwt;
public function __construct(JWTAuth $jwt)
{
$this->jwt = $jwt;
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email|max:255',
'password' => 'required',
]);
try {
if (! $token = $this->jwt->attempt($request->only('email', 'password'))) {
$create_token = User::where('user_id', $login->user_id)->update(['token' => $token]);
return response()->json(['user_not_found'], 404);
}
else {
$create_token = User::where('user_id', auth()->user()->user_id)->update(['token' => $token]);
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], 500);
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], 500);
} catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent' => $e->getMessage()], 500);
}
return response()->json(compact('token'));
}
public function logout(Request $request)
{
$this->jwt->invalidate($this->jwt->getToken());
return response()->json([
'message' => 'User logged off successfully!'
], 200);
}
}
I tried the method above but i got error saying Call to undefined function App\Http\Controllers\auth()
can anyone help me??
Not advised seeing that json web tokens are time sensitive but I did write something similar but for the use of redis. Looking at your code I would advise you create row for tokens and add it to the public $hidden = ['password','token']. When a user is created, you create and save a token to the database.
Related
I want to use Rule::unique method to handle if $request->code with status="in process" are already exist in special_code table inside FormRequest file, here's the code
class CreateRequest extends FormRequest {
// ..............
public function rules()
{
return [
'username' => ['required'],
'code' => [
'required',
Rule::unique('special_code', 'code')->where(function ($query) {
return $query->where('status', 'in process');
}),
],
]
}
// ..............[ there is also custom message here ]
}
the Rule::unique' is work very well, but the problem is, if the validation is failed (that mean the condition for data code with status=in process is already exists, the catch is called inside that FormRequest, not from the controller, here's my controller code
public function save(CreateRequest $request) {
try {
$validated = $request->validated();
// ..............
} catch (ValidationException $e) {
$validator = $e->validator;
$errors = $validator->errors();
$key = array_key_first($errors->messages());
$toastr_message = $errors->messages()[$key][0];
return response()->json([
'status' => 'error',
'message' => $toastr_message,
], 422);
}
}
Btw, if the catch is called inside the controller, the response should be
{"status":"error", "message":"code is xxxxxxxxxxxxxxx"}
not like this
{"message":"code is xxxxxxxxxxxxxxx","errors":{"code":["code is xxxxxxxxxxxxxxx"]}}
Solved, i add this function inside FormRequest file
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
return redirect()->back()
->withErrors($validator)
->withInput();
}
I'm using Laravel and JWT, and I want to login without password.
When I use auth()->login($user), I got null, so I can not get token, why?
I'm sure $user is not null.
api\UserController.php
<?php
namespace App\Http\Controllers\api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class UserController extends Controller
{
public function login(Request $request)
{
try{
if(User::where("account", $request->account)->exists()){
$user = User::where("account", $request->account)->get()->first();
if (!$token = auth()->login($user)) {
return response()->json(['message' => 'login failed'], 404);
}else{
return response()->json(['token' => $token], 200);
}
}
else{
return response()->json([
"message" => "login failed"], 404);
}
}
catch(Throwable $e){
return response()->json([
"message" => "login failed"], 404);
}
}
}
Laravel version : 7.9.2
PHP version: 7.4
I have code for login with Facebook and Google. It's working absolutely fine on localhost but on live server it doesn't work. Surprising thing is It neither returns any error nor throw any exception.
It simply redirect user back to login page and my URL shows the string #=.
This is live link
https://beta.car-chain.net/login
I need suggestion.
LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use App\User;
use Exception;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct()
{
$this->middleware('guest')->except('logout');
}
protected $providers = [
'github','facebook','google','twitter'
];
public function show()
{
return view('auth.login');
}
public function redirectToProvider($driver)
{
if( ! $this->isProviderAllowed($driver) ) {
return $this->sendFailedResponse("{$driver} is not currently supported");
}
try {
return Socialite::driver($driver)->redirect();
} catch (Exception $e) {
// You should show something simple fail message
return $this->sendFailedResponse($e->getMessage());
}
}
public function handleProviderCallback( $driver )
{
try {
$user = Socialite::driver($driver)->user();
} catch (Exception $e) {
return $this->sendFailedResponse($e->getMessage());
}
// check for email in returned user
return empty( $user->email )
? $this->sendFailedResponse("No email id returned from {$driver} provider.")
: $this->loginOrCreateAccount($user, $driver);
}
protected function sendSuccessResponse()
{
return redirect()->intended('home');
}
protected function sendFailedResponse($msg = null)
{
return redirect()->route('social.login')
->withErrors(['msg' => $msg ?: 'Unable to login, try with another provider to login.']);
}
protected function loginOrCreateAccount($providerUser, $driver)
{
// check for already has account
$user = User::where('email', $providerUser->getEmail())->first();
// if user already found
if( $user ) {
// update the avatar and provider that might have changed
$user->update([
'provider' => $driver,
'provider_id' => $providerUser->id,
'access_token' => $providerUser->token
]);
} else {
if($providerUser->getEmail()){ //Check email exists or not. If exists create a new user
$user = User::create([
'name' => $providerUser->getName(),
'email' => $providerUser->getEmail(),
'provider' => $driver,
'provider_id' => $providerUser->getId(),
'access_token' => $providerUser->token,
'password' => '' // user can use reset password to create a password
]);
}else{
//Show message here what you want to show
}
}
// login the user
Auth::login($user, true);
return $this->sendSuccessResponse();
}
private function isProviderAllowed($driver)
{
return in_array($driver, $this->providers) && config()->has("services.{$driver}");
}
}
Route.php
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('auth/social', 'Auth\LoginController#show')->name('social.login');
Route::get('oauth/{driver}', 'Auth\LoginController#redirectToProvider')->name('social.oauth');
Route::get('oauth/{driver}/callback', 'Auth\LoginController#handleProviderCallback')->name('social.callback');
I was able to login and get user token using JWT in laravel.However, while tring to get authenticated user (getAuthUser) by passing that token, I get following error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'where
clause' (SQL: select * from user where `` = 12 limit 1)"
AuthenticationController:
<?php
namespace Modules\Authentication\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
use JWTAuth;
use JWTAuthException;
use Modules\Settings\Entities\Users;
use Modules\Authentication\Http\Requests\Authentication;
class AuthenticationController extends Controller
{
public function __construct()
{
// $this->user = new Users;
$this->guard = \Auth::guard('api');
}
public function login(Authentication $request){
$credentials = $request->only('username', 'password');
try {
// verify the credentials and create a token for the user
$token = JWTAuth::attempt($credentials);
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'));
}
public function getAuthUser(Request $request){
$user = JWTAuth::user($request->token);
// dd($user);
return response()->json(['result' => $user]);
}
}
Users Model:
namespace Modules\Settings\Entities;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Users extends Model implements JWTSubject,Authenticatable{
Protected $table="user";
// protected $primaryKey = 'id';
protected $fillable = ['id','username','password','user_status_type_id','client_id','created_userid'];
protected $hidden = [
'password', 'remember_token',
];
public function user_status(){
return $this->belongsTo('Modules\Settings\Entities\UserStatusType','user_status_type_id');
}
public function user_client(){
return $this->belongsTo('Modules\Settings\Entities\Client','client_id');
}
public function role()
{
return $this->belongsToMany('Modules\Settings\Entities\Role','user_role','user_id','role_type_id');
}
public function getAuthPassword() {
return $this->password;
}
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
public function getAuthIdentifierName(){}
public function getAuthIdentifier(){}
// public function getAuthPassword(){}
public function getRememberToken(){}
public function setRememberToken($value){}
public function getRememberTokenName(){}
}
Route:
Route::group(['middleware' => 'web', 'prefix' => 'api/v1/authentication', 'namespace' => 'Modules\Authentication\Http\Controllers'], function(){
Route::post('auth/login', 'AuthenticationController#login');
// Route::group(['middleware' => 'jwt.auth'], function () {
Route::get('user', 'AuthenticationController#getAuthUser');
// });
});
I am testing it in postman by
GET: ..../api/v1/authentication/user?token={Token}
EDIT:
Now my method for getAuthUser in the controller looks like this:
public function getAuthUser(Request $request){
// $token = JWTAuth::getToken();
// dd($token);
$input = $request->all();
JWTAuth::setToken($input['token']);
// dd($input['token']);
$user = JWTAuth::toUser($input['token']);
// dd($user);
return response()->json(['result' => $user]);
}
and In JWTAuth.php
public function authenticate()
{
// dd($this->getPayload()->get('sub'));
$id = $this->getPayload()->get('sub');
// dd($id);
// dd($this->auth->byId($id));
if (! $this->auth->byId($id)) {
return false;
}
return $this->user();
}
here by doing dd($id), value of id comes but if I try to do dd($this->auth->byId($id)) I get the same error as before.
Try this to retrieve the user instead:
public function getAuthUser()
{
try {
if (! $user = JWTAuth::parseToken()->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->getStatusCode());
}
// the token is valid and we have found the user via the sub claim
return response()->json(['result' => $user]);
}
Taken from docs, Retreiving the Authenticated user from a token
EDIT:
May not make a difference but just looking at your Model again and I would say that it needs to be
class Users extends Authenticatable implements JWTSubject
rather than
class Users extends Model implements JWTSubject,Authenticatable
I am trying to implement multi auth in laravel 5.4 and have done it in this way,
i have already implemented guards and providers for the guards in auth.php,
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class FleetLoginController extends Controller {
public function __construct() {
$this->middleware('guest:company');
}
public function showLogInForm() {
return view('fleet.fleetLogin');
}
public function login(Request $request) {
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::guard('company')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) {
$request->session()->regenerate();
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
} else {
return redirect()->back()->withInput($request->only('email', 'remember'));
}
}
public function logout(Request $request) {
$this->guard('company')->logout();
$request->session()->invalidate();
return redirect('/');
}
public function logcheck() {
if (Auth::check()) {
dd('yes logged in');
}
else
{
dd('No user logged in');
}
}
protected function authenticated(Request $request, $user) {
$this->logcheck();
}
protected function guard() {
return Auth::guard('company');
}
}
i have made the providers and guards, the problem is when i call the function logcheck()
it dumps "No user logged in". Can anyone help me? i need to get the id of the logged in user by
Auth::User()->id;
Seems like you need to use send name to guard
Auth::guard('company')->check() on logcheck()