I'm trying to pass token_id and user_id from controller to middleware.
I have some hard time with that.
This is the code that I'm trying to run.
class UserController extends Controller
{
protected $user_id;
protected $token_id;
public function __construct()
{
$user_id = $this->user_id;
$token_id = $this->token_id;
$together = $user_id . ':' . $token_id;
$this->middleware('check.auth:' . $together);
}
public function setLogin(Request $request)
{
$credentials = request(['email', 'password']);
if (!Auth::attempt($credentials)){
Secure::checkFailedAuth($request->email, $request->password);
return response()->json(['response' => false, 'status' => 400, 'message' => 'Provided details are not correct!'], 400);
}
$user = Auth::user();
$tokenResult = $user->createToken($user->name);
$token = $tokenResult->token;
$token->save();
$this->user_id = Auth::id();
$this->token_id = $tokenResult->token->token_id;
return response()->json(['result' => true, 'status' => 200, 'message' => 'Login Successful', 'data' => Auth::user(), 'token' => $tokenResult->accessToken ], 200);
}
When I run that I have no errors, but there is null on both user_id and token_id.
Any ideas why?
Related
I have this feature test
public function it_can_logout()
{
$user = User::find(1);
$this->assertNotNull($user);
$credentials = [
'email' => $user->email,
'password' => 'password',
];
$loginResponse = $this->postJson('api/login', $credentials);
$loginResponse->assertStatus(200);
$response = $this->post('api/logout');
$response->assertStatus(200);
$response->assertJson(['status' => true, 'message' => 'logged out']);
$this->assertGuest();
}
and this method to be tested
public function logout(Request $request)
{
auth('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return response()->json([
'status' => true,
'message' => 'logged out'
], 200);
}
But when running
php artisan test --filter=it_can_logout
I have this issue
Session store not set on request
I am made an App with Laravel 9 back-end and ReactJS front-end and get a 401 unauthorized error even I am successfully logged-in in to my App. For Authentication I am using Laravel's build-in Passport and Cross-Domain Middleware.
Code is in api.php router and looks like below:
Route::group(['prefix' => 'users', 'middleware' => 'CORS'], function ($router) {
Route::post('/register', [AuthController::class, 'register'])->name('register.auth');
Route::post('/login', [AuthController::class, 'login'])->name('login.auth');
Route::get('/userdata', [AuthController::class, 'userData'])->name('userdata.auth');
Route::get('/checkifemailverified/{token}', [AuthController::class, 'checkIfEmailVerified'])->name('user.verify');
Route::get('/logout', [AuthController::class, 'logout'])->name('logout.auth');
Route::get('/me', [AuthController::class, 'me'])->name('me.auth');
});
And here is a AuthController:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Auth;
use App\Models\User;
use App\Models\UserVerify;
use Validator;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
use Mail;
use Illuminate\Support\Facades\View;
class AuthController extends Controller
{
//private $apiToken;
protected $user;
public function __construct()
{
//$this->apiToken = uniqid(base64_encode(Str::random(40)));
$this->middleware("auth:api",["except" => ["login","register","logout","verifyAccount","checkIfEmailVerified","me"]]);
$this->user = new User;
}
/**
*
* #return \Illuminate\Http\Response
*/
public function login(Request $request){
$validator = Validator::make($request->all(),[
'email' => 'required|string',
'password' => 'required|min:8',
]);
if($validator->fails()){
return response()->json([
'success' => false,
'message' => $validator->messages()->toArray()
], 500);
}
//User check
$credentials = $request->only(["email","password"]);
$user = User::where('email',$credentials['email'])->first();
if($user->is_active===1){
if(auth()->attempt($credentials)){
//$user = Auth::user();
if($user->email_verified_at !== NULL){
if (DB::table('domains')
->select('domain', 'valid_before')
->where('domain', $user->domain)
->whereDate('valid_before_at', '<=', Carbon::now())
->count()){
return response()->json([
'success' => false,
'data' => 'Username and password do not match or domain subscription is not valid or expired!'
], 200);
} else {
// Login and "remember" the given user...
//Auth::login($user, true);
//Setting login response
$accessToken = auth()->user()->createToken('authToken')->accessToken;
/*$success['token'] = $this->apiToken;
$success['name'] = $user->name;
return response()->json([
'success' => true,
'data' => $success
], 200);*/
$responseMessage = "Login Successful";
return $this->respondWithToken($accessToken,$responseMessage,auth()->user());
}
} else {
return response()->json([
'success' => false,
'data' => 'Please Verify Email!'
], 200);
}
} else {
//$success['success'] = false;
return response()->json([
'success' => false,
'data' => 'Username and password do not match or domain subscription is not valid or expired!'
], 200);
}
}
}
public function register(Request $request){
$validator = Validator::make($request->all(),[
'email' => 'required|string',
'name' => 'required|string',
'domain' => 'required|string',
'password' => 'required|min:8',
]);
if($validator->fails()){
return response()->json([
'success' => false,
'message' => $validator->messages()->toArray()
], 500);
}
DB::beginTransaction();
try {
DB::table('domains')->insert([
['domain' => $request->domain, 'valid_before_at' => date('Y-m-d H:i:s', strtotime("+30 day")), 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]
]);
DB::table('users')->insert([
['name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), 'domain' => $request->domain]
]);
DB::commit();
// all good
/*return response()->json([
'success' => true,
'data' => 'User and domain is now created!'
], 200);*/
try {
$id = DB::table('users')
->select('id')
->where('email', $request->email)
->first()->id;
$token = Str::random(64);
DB::table('users_verify')->insert([
['user_id' => $id, 'token' => $token, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')]
]);
Mail::send('emails.userverify', ['token' => $token], function($message) use($request){
$message->from(env('MAIL_FROM_ADDRESS'), env('MAIL_FROM_NAME'));
$message->to($request->email);
$message->subject('Email Verification Mail');
});
return response()->json([
'success' => true,
'data' => 'User and domain is now created!'
], 200);
} catch (\Exception $e) {
// something went wrong
return response()->json([
'success' => false,
'data' => $e->getMessage()
], 200);
}
} catch (\Exception $e) {
DB::rollback();
// something went wrong
return response()->json([
'success' => false,
'data' => $e->getMessage()
], 200);
}
}
/**
* Write code on Method
*
* #return response()
*/
public function verifyAccount($token)
{
$verifyUser = UserVerify::where('token', $token)->first();
$message = 'Sorry your email cannot be identified.';
if(!is_null($verifyUser) ){
$user = $verifyUser->user;
if($user->email_verified_at == null) {
$verifyUser->user->email_verified_at = date('Y-m-d H:i:s');
$verifyUser->user->save();
$message = "Your e-mail is verified. You can now login.";
} else {
$message = "Your e-mail is already verified. You can now login.";
}
}
return redirect(env('APP_UI_URL').'/verifyemail?token='.$token);
}
/**
* Write code on Method
*
* #return response()
*/
public function checkIfEmailVerified($token)
{
$verifyUser = UserVerify::where('token', $token)->first();
$message = 'Sorry your email cannot be identified.';
if(!is_null($verifyUser) ){
$user = $verifyUser->user;
if($user->email_verified_at == null) {
$message = "Your e-mail is verified. You can now login.";
} else {
$message = "Your e-mail is already verified. You can now login.";
}
}
return response()->json([
'success' => true,
'data' => $message
], 200);
}
/**
* Logout the current user and revokes its crenedials.
*
* #return response()
*/
public function logout(Request $request){
$user = Auth::guard("api")->user()->token();
$user->revoke();
$responseMessage = "successfully logged out";
return response()->json([
'success' => true,
'message' => $responseMessage
], 200);
}
/**
* Get the user's profile.
*
* #param Request $request
* #return Response
*/
public function userData(Request $request)
{
$data = Auth::guard("api")->user();
//var_dump($user);
return $data;
}
/**
* Get the user's profile name.
*
* #param Request $request
* #return Response
*/
public function me(Request $request)
{
$data = Auth::guard("api")->user();
//var_dump($data);
return $data;
}
}
Purpose is to get logged-in users details for ReactJS GUI with userdata route and/or me router user name E.g Matti Kiviharju.
Also if anyone wants to see whole source codes of am App there re publically here in my GIT repositories in Atlassian Bitbucket for investigation:
React Front-end: https://bitbucket.i4ware.fi/projects/LOG/repos/login-form/browse?at=refs%2Fheads%2Fmatti_0006
Laravel Back-end: https://bitbucket.i4ware.fi/projects/SAAS/repos/saas-app/browse?at=refs%2Fheads%2Fmatti_0008
However, right answer for this that solves a problem helps multiple people, because source codes is available on our public GIT repos.
I created a Laravel App. It could access through web, for admin's web page, and api for user's page. I created user's page using Vue so it needs API.
Doing so, I need two Auth Controller. One is automatically created using laravel scaffolding, for the web. And the other is created manually for user's login via token.
I did create the AuthController for API. This is the controller.
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
class AuthController extends Controller
{
//untuk login
public function login(Request $request)
{
//validasi data
$this->validate($request, [
'email' => 'email',
'username' => 'string',
'password' => 'required'
]);
//login dapat menggunakan email atau username
$user = User::where('email', '=', $request->email)
->orWhere('username', '=', $request->username)->first();
// $username = User::where('username', $request->username)->first();
// dd($username);
$status = "error";
$message = "";
$data = null;
$code = 401;
// echo (gettype($email));
// echo(gettype($username));
// echo($email);
if($user){
if (Hash::check($request->password, $user->password)){
$user->generateToken(); //generated 60 random string
$status = 'success';
$message = 'Login Success';
//tampilkan data user menggunakan method to Array
$data = $user->toArray();
$code = 200;
}
else{
$message = "Login gagal, password salah";
}
}
else {
$message = "Login gagal, username atau email salah";
}
return response()->json([
'status' => $status,
'message' => $message,
'data' => $data,
], $code);
}
//untuk registrasi
public function register(Request $request)
{
$validator = Validator::make($request->all(),
[
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
'username' => 'string'
]);
if ($validator->fails()){
$errors = $validator->errors();
return response()->json([
'data' => [
'message' => $errors,
]
],400);
}
else{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'username' => $request->username,
'roles' => json_encode(['CUSTOMER'])
]);
if ($user){
$user->generateToken();
$status = "success";
$message = "Register berhasil!";
$data = $user->toArray();
$code = 200;
}
else{
$message = "Register gagal";
}
return response()->json([
'status' => $status,
'message' => $message,
'data' => $data
], $code);
}
}
//untuk logout
public function logout(Request $request)
{
//get authenticated user data
$user = Auth::user();
if($user){
$user->api_token = null; //delete user's token
$user->save();
}
return response()->json([
'status' => 'success',
'message' => 'logout success,
'data' => null,
], 200);
}
}
Login and Register method is worked. But when i try to run Logout method, i get AuthenticationException. I tried to debug the $user variable at Logout method, it return null. So, that's why i get the error. My question is, how i solve it? Is it even possible to create two different authentication controller in laravel?
For clarity, this is my api.php
//Routing bersifat publik
Route::prefix('v1')->group(function (){
Route::post('login', 'API\AuthController#login');
Route::post('register', 'API\AuthController#register');
Route::get('books', 'API\ApiBookController#index');
Route::get('book/{id}', 'API\ApiBookController#view')
->where('id', '[0-9]+');
Route::resource('categories', 'API\ApiCategoryController')
->except(['create', 'update']);
//Routing bersifat private
Route::middleware('auth:api')->group(function (){
Route::post('logout', 'API\AuthController#logout');
});
});
Logout method response:
{
"status": "error",
"message": "Unauthenticated.",
"data": null,
"errors": {
"exception": "Illuminate\\Auth\\AuthenticationException",
"trace": [
"#0 D:\\xampp\\htdocs\\book-store\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Middleware\\Authenticate.php(68): Illuminate\\Auth\\Middleware\\Authenticate->unauthenticated(Object(Illuminate\\Http\\Request), Array)"
]
}
}
Thank you for your time and consideration.
config\auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
*Note: default guard in config\auth.php is web so i can log in to the web.
Use auth guard..
$user=Auth::guard('api')->user();
you have to specific what user should be logout in your controller in the apiController
you should change
$user = Auth::user();
to
$user = Auth::guard('api')->user();;
then logout him.
I have a AuthController where I register the user and also log in the user. When the user is registered, I automatically log the user in by calling the login method. The login method returns a JSON object that looks like this
"meta": {
"headers": {},
"original": {
"success": true,
"token": "token is here"
},
"exception": null
}
How do I extract token from that JSON object that I get from $this->login($request)? Because right now $token returns Null.
public function login(Request $request)
{
$input = $request->only('email', 'password');
$token = null;
if (!$token = JWTAuth::attempt($input)) {
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], 401);
}
return response()->json([
'success' => true,
'token' => $token,
]);
}
public function register(RegistrationFormRequest $request)
{
$user = new User();
$user->user_name = $request->user_name;
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->email = $request->email;
$user->password = bcrypt($request->password);
$user->role_id = 7;
$user->subscription_plan_id = 1;
$user->save();
$token = json_decode($this->login($request), TRUE)['token'];
return response()->json([
'success' => true,
'data' => $user,
'meta' => $token,
], 200);
}
'facebook' => [
'client_id' => 'id',
'client_secret' =>
'fgdfgsdfgrtt45453',
'redirect' => 'http://example.com/callback',
],
In route.php
Route::get('/redirect', 'SocialAuthFacebookController#redirect');
Route::get('/callback', 'SocialAuthFacebookController#callback');
And I have add Services/SocialFacebookAccountService.php directory in App.
SocialFacebookAccountService.php
<?php
namespace App\Services;
use App\SocialFacebookAccount;
use App\User;
use Laravel\Socialite\Contracts\User as ProviderUser;
class SocialFacebookAccountService {
public function createOrGetUser(ProviderUser $providerUser) {
$account = SocialFacebookAccount::whereProvider('facebook')
->whereProviderUserId($providerUser->getId())
->first();
echo 'Account info : ';
if ($account) {
return $account->user;
} else {
$account = new SocialFacebookAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => 'facebook'
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
'password' => md5(rand(1, 10000)),
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
Please help, How to get user info in callback.
In your callback method:
public function callback($provider=facebook)
{
if($user = $this->socialite->with($provider)->user()){
dd($user); //user details
}else{
return 'something went wrong';
}
}