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);
}
}
}
Related
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 make an admin panel using laravel 6.0 I want to make a guard to my admin panel for when trying access without login and then should redirect back to the login page. I tried these code but I got errors. route defined so I can't figure out the problem.
this is the error
Handler.php
Symfony\Component\Routing\Exception\RouteNotFoundException
Route [login] not defined.
<?php
namespace App\Exceptions;
use Exception;
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
protected $dontReport = [
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
public function unauthenticated($request, AuthenticationException $exception)
{
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'admin':
return redirect()->guest(route('login'));
break;
default:
return redirect('/user/login');
break;
}
}
}
web.php
<?php
Route::prefix('admin')->group(function() {
Auth::routes();
Route::middleware('auth:admin')->group(function() {
Route::get('/', 'DashboardController#index');
Route::resource('/manageSISAccount', 'SISAccountController');
Route::get('/confirm/{id}','SISAccountController#confirm')->name('SIS.confirm');
Route::get('/pendig/{id}','SISAccountController#Pending')->name('SIS.Pending');
Route::get('/shpw/{id}','SISAccountController#show')->name('SIS.show');
Route::get('/logout','AdminUserController#logout');
});
Route::get('/login','AdminUserController#index');
Route::post('/login', 'AdminUserController#store');
});
AdminUserController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminUserController extends Controller
{
public function __construct()
{
$this->middleware('guest:admin')->except('logout');
}
public function index(){
return view('admin.adminlogin');
}
public function store(Request $request) {
// Validate the user
$request->validate([
'email' => 'required|email',
'password' => 'required'
]);
// Log the user In
$credentials = $request->only('email','password');
if (! Auth::guard('admin')->attempt($credentials)) {
return back()->withErrors([
'message' => 'Wrong credentials please try again'
]);
}
// Session message
session()->flash('msg','You have been logged in');
return redirect('/admin');
}
public function logout() {
auth()->guard('admin')->logout();
session()->flash('msg','You have been logged out');
return redirect('/admin/login');
}
}
You did not name your login route.
Change:
Route::get('/login','AdminUserController#index');
To:
Route::get('/login','AdminUserController#index')->name('login');
For more information about naming routes: https://laravel.com/docs/6.x/routing#named-routes
Route::get('/login',['uses'=>'AdminUserController#index#index','as'=>'login']);
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 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.
I have created a laravel project to login with socialite recently.
I have an deactivate account function for Admin. I have my codes to prevent my users to login if their status is 1 (which is deactivated) but these codes doesn't work with user who use socialite function to login.
My codes to prevent deactivate user to login as shown below.
protected function authenticated($request, $user){
if(Auth::attempt(['email' => $request->email, 'password' => $request->password, 'status' => 0]))
{
if($user->role == 2)
{
return redirect()->intended('/admin/users');
}else{
return redirect()->intended('/');
}
}else{
Auth::logout();
return back()->with('error', 'Your account is deactivated.');
}
}
Controller for socialite
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\SocialAccountService;
use Socialite;
use App\User;
class SocialAuthController extends Controller
{
public function FacebookRedirect()
{
return Socialite::driver('facebook')->redirect();
}
public function FacebookCallback(SocialAccountService $service)
{
$fbUser = $service->FacebookCreateOrGetUser(Socialite::Driver('facebook')->user());
auth()->login($fbUser);
return redirect()->to('/');
//$facebookUser = Socialite::driver('facebook')->user();
//$facebookFirstnameAccess = $facebookUser->user['first_name'];
//echo $facebookFirstnameAccess;
//dd($facebookUser);
}
public function GoogleRedirect()
{
return Socialite::driver('google')->redirect();
}
public function GoogleCallback(SocialAccountService $service)
{
$Guser = $service->GoogleCreateOrGetUser(Socialite::Driver('google')->user());
auth()->login($Guser);
//$googleUser = Socialite::driver('google')->user();
return redirect()->to('/');
//$fName = $googleUser->firstname = $googleUser->user['name']['givenName'];
//$lName = $googleUser->lastname = $googleUser->user['name']['familyName'];
//echo $lName;
//dd($googleUser);
}
}
Is there anywhere for me to prevent the user to login with socialite if I have deactivated their account?