I am using a custom table customer for login and also Laravel Passport to generate token for my Ionic mobile app. I am stuck at the login code where I need to generate token after query from my custom table.
Below are the login code... I can successfully retrieve the id from database but how to link it with the token?
public function login(Request $request)
{
$phone = $request->input('phone');
$password = $request->input('password');
$user = $token = array();
try {
$rs_login = DB::select("select a.id from customer a where a.active > 0 and a.phone = ? and a.password = ?", [$phone, $password]);
$numrow_login = count($rs_login);
if ($numrow_login != 1) {
$this->error['form-message'] = 'ERR' . __LINE__ . ': Invalid phone number or password';
} else {
$user['id'] = $rs_login[0]->id;
}
} catch (\Illuminate\Database\QueryException $ex) {
$this->error['form-message'] = 'Login service is unavailable';
}
if ($this->error == '') {
$tokenResult = $user['id']->createToken('Personal Access Token'); // How to pass the $user['id'] to generate token?
$token = $tokenResult->token;
$token->save();
$token['access_token'] = $tokenResult->accessToken;
$token['token_type'] = 'Bearer';
$token['expires_at'] = Carbon::parse(
$tokenResult->token->expires_at
)->toDateTimeString();
}
if ($this->error == '') {
$response['status'] = 'success';
$response['message'] = 'Login successful';
$response['token'] = $token;
} else {
$response['status'] = 'error';
$response['error'] = $this->error;
$response['message'] = (isset($this->error['form-message'])) ? $this->error['form-message'] : 'Please check the form';
}
return response()->json($response);
}
You can just specify a custom table in the config/auth.php instead of rewriting the entire logic
'api' => [
'driver' => 'token',
'provider' => 'customer', // <--- Here
'hash' => false,
],
And create the provider to use the specific table from the database
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'customer' => [
'driver' => 'database',
'table' => 'customer',
],
],
And keep the default login behavior for passport
Hope this helps
// changes to be made in this file: config/auth.php
// Create a custom model to override the User model
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
//custom provider
'customProvider' => [
'driver' => 'eloquent',
'model' => App\CustomModel::class, // put custom model here
],
],
// attach your custom provider within the api guard to use with api calls
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'customProvider', // put custom provider here
],
],
// Use lik this in your api router
Route::group(['middleware' => 'auth:api'], function() {});
// I used it like this in LoginController
$user = CustomModel::where('email', $request -> email) -> first();
if(!Hash::check($request -> password, $user -> password)){
return response()->json(['message' => 'Authentication failed. Please check your
credentials and try again!'], 401);
}
Auth::login($user);
$accessToken = Auth::user() -> createToken('authToken') -> accessToken;
Related
So I have login page that the admin or users can use to login. It went well until such time we have some changes and added the admin side. I only uses 1 table for all user types and I have role_id column that defines the users role. So if the role_id is 0, I have to redirect them to the dashboard page whereas if it's a user, will redirect to user page. I have tried as what is suggested in the internet but can't make it work. Here's what I have:
class UserLoginController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest:user')->except('logout');
}
public function showLoginForm()
{
return view('auth.user-login');
}
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
// if successful, then redirect to their intended location
return redirect()->intended(route('user.dashboard'));
}
// if unsuccessful, then redirect back to the login with the form data
if (! User::where('email', $request->email)->where('password', bcrypt($request->password))->first() ) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
}
public function logout()
{
Auth::guard('user')->logout();
return redirect()->route('user.login');
}
}
config/auth
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'guest' => [
'driver' => 'session',
'provider' => 'guests',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'guests' => [
'driver' => 'eloquent',
'model' => App\Guest::class,
],
],
MODEL
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $guard = 'user';
protected $fillable = [
//fillable cols
];
//change role id data type to integer
protected $casts = [
'role_id' => 'integer',
];
}
Now, where should I insert the condition to check if it's an admin or a user?
You can try it
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (!Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
$user = Auth::guard('user')->user();
if ($user->role_id === 0) {
return redirect()->route('user.dashboard');
}
return redirect()->route('user.page');
}
Check below i have edited the method of login:
public function login(UserLoginRequest $request)
{
// Attempt to log the user in
if (Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password])) {
// Over here this condition will be true when user is successfully login
// Below is the user data i have printed in that you can check the role of user which is login.
$user = Auth::user();
print_r($user);
}
// if unsuccessful, then redirect back to the login with the form data
if (! User::where('email', $request->email)->where('password', bcrypt($request->password))->first() ) {
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['status' => 'Incorrect username or password.']);
}
}
I am a novice with Lumen and have recently integrated dusterio/lumen-passport via composer into my project. Following a tutorial I have successfully created authentication for 'client' instances, so I am able to send variables
grant_type: client_credentials
client_id: {my id}
client_secret: {my secret}
to /oauth/token and get a bearer token. That is working great.
What I need to be able to do, and I cannot find sufficient documentation anywhere, is to create user login functionality. This is so that I can hook a UI up to the Lumen API and users be able to enter their email address and password to get access. If any one has any information to help me achieve this I would be extremely grateful. Below are edits I have made to set up the passport process...
bootstrap/app.php
$app->routeMiddleware([
'client.credentials' => Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
]);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(Laravel\Passport\PassportServiceProvider::class);
$app->register(Dusterio\LumenPassport\PassportServiceProvider::class);
config/auth.php
'defaults' => [
'guard' => env('AUTH_GUARD', 'api'),
'passwords' => 'users'
],
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users'
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => \App\User::class
]
],
routes/web.php
$router->group(['middleware' => 'client.credentials'], function () use ($router) {
$router->get('/test', 'TestController#index');
});
The way I did it with my laravel based client (seperate apps) was to save the token to a cookie which gets called each request using middleware to authenticate the request heres my code.
<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
class AuthController extends Controller {
public function __construct()
{
}
public function showLoginPage()
{
return view('Login');
}
public function attemptLogin(Request $request)
{
$client_id = env('CLIENT_ID');
$client_secret = env('CLIENT_SECRET');
$username = $request->input('email');
$password = $request->input('password');
$guzzle = new Client;
$response = $guzzle->post('https://api.domain.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => $client_id,
'client_secret' => $client_secret,
'username' => $username,
'password' => $password,
'scope' => '*',
],
]);
$reply = json_decode($response->getBody(), true);
$token = $reply['access_token'];
return redirect('/')->cookie('token', $token);
}
public function attemptLogout(Request $request)
{
$accessToken = $request->cookie('token');
$client = new Client(['base_uri' => 'https://api.domain.com']);
$headers = [
'Authorization' => 'Bearer ' . $accessToken,
'Accept' => 'application/json',
];
$response = $client->request('GET', 'logout', [
'headers' => $headers
]);
$status = $response->getStatusCode();
if($status === 200)
{
return redirect('/login')->withCookie(Cookie::forget('token'))->with('success','Logout Successful');
} else {
return response('API Logout Failed', 500);
}
}
}
I'm building an app that has pricing. I would want to assign some special price to some specific users.
In the model that has the price, I'm trying to use an accessor to "tweak" the price like so:
public function getPriceAttribute($price)
{
dd(auth()->user()); //this returns null
if (auth()->check()) {
$user = auth()->user();
return $user->aDefinedRelationship()->first()->price;
}
return $price;
}
However auth()->user() always returns null.
I'm using the traditional Laravel authentication, no external library.
Please is there something I'm not doing right?
Any help would be appreciated.
More information:
auth.php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Api\V1\Models\User::class,
],
],
];
ThePriceModel.php
namespace App\Api\V1\Models;
use Illuminate\Database\Eloquent\Model;
class ThePriceModel extends Model
{
protected $table = 'prices';
protected $fillable = ['code', 'price'];
public function getPriceAttribute($price)
{
dd(auth()->user()); //this returns null
if (auth()->check()) {
$user = auth()->user();
return $user->aDefinedRelationship()->first()->price;
}
return $price;
}
}
After every other thing failed, I resorted to using a global config variable.
in config/constants.php:
return [
...
'user' => []
];
somewhere in my controller:
config()->set('constants.user', auth()->user());
Then in the model:
...
public function getPriceAttribute($price)
{
$user = config()->get('constants.user');
...
}
I suppose you were using API and this is why it didn't work. You could check for the user using this. You need to check API guard.
$user = \Auth::user() ?? \Auth::guard("api")->user();
I have 2 user i.e user and bus and for them i have different model
I am using laravel 5.5 with tymondesigns/jwt-auth 1.0.0-rc.1 verson
user is working perfect for user i am getting token also
but bus user us getting 'invalid_email_or_password'
link to full code full source code link
here is my user model:
class User extends Authenticatable implements JWTSubject{
use Notifiable;
protected $fillable = ['name', 'email', 'password'];
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}}
my config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'bus' => [
'driver' => 'session',
'provider' => 'buses',
],
'bus-api' => [
'driver' => 'jwt',
'provider' => 'buses',
],
],
my provider are :
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
//next
'buses' => [
'driver' => 'eloquent',
'model' => App\Bus::class,
],
my
my buslogincontroller which is taking user name & password for user table
public function busLogin(Request $request)
{
\Config::set('jwt.user', "App\Bus");
\Config::set('auth.providers.users.model', \App\Bus::class);
$credentials = $request->only('email', 'password');
try {
\Config::set('jwt.user', "App\Bus");
\Config::set('auth.providers.users.model', \App\Bus::class);
if (!$token = JWTAuth::attempt($credentials)) {
\Config::set('jwt.user', "App\Bus");
\Config::set('auth.providers.users.model', \App\Bus::class);
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am Admin user',
'user' => '99',
],
]);
}
my routes api:
Route::post('bus/auth/login', 'Bus\Auth#busLogin');
Route::post('bus/auth/register', 'Bus\Auth#busRegister');
whenever I try to login with Bus model username & password i get invalid login in buscontroller login route but if i try to login with user model credintials i get token in return
how to setup multiple auth with jwtauth with laravel 5.5
There is no need to change the providers in config/auth.php.
You can change the __construct function in each of your controllers as follows. So that jwt know which model to authenticate.
BusController
function __construct()
{
Config::set('jwt.user', Bus::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Bus::class,
]]);
}
AdminController
function __construct()
{
Config::set('jwt.user', Admin::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Admin::class,
]]);
}
You just need to set below code before route call in route api
\Config::set('jwt.user', "App\Bus");
\Config::set('auth.providers.users.model', \App\Bus::class);
I want to create JWT using client model. All the login credentials are saved in the clients table. Here in my Laravel 5.4 application I dont want to have users model. My piece of code is being showing. Now when I am trying to login laravel querying from users table which I don't. I want it from clients table. All the required namespaces I have added top in my controller file. Need help to get a solution.
\Config::set('jwt.user', 'App\Client');
\Config::set('auth.providers.users.model', \App\Client::class);
$credentials = ["username"=>$user_name,"password"=>$password];
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am front user',
],
]);
I think you need to change the providers => users => model => to your custom namespace in config/auth.php
Example
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class, <= change this to your custom namespace
],
],