Laravel - Alternative for Session in Laravel Socialite Login in Rest API - laravel

I am new to Laravel Socialite Login. In my Laravel-8 Application, I have used:
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
for Azure Socialite Login, which works for the multi-company Login. I store the company id in Session.
public function getCompanies() {
$current_domain = request()->getHost(); // your company app name
$domain = explode('.', $current_domain);
return OrgCompany::where('subdomain', $domain[0])->firstOrFail();
}
public function redirectToProvider(Request $request, OrgSocialiteSetting $azureCredential)
{
$companies = $this->getCompanies();
if($companies){
$company_credentials = OrgSocialiteSetting::where('id', $companies->id)->first();
//when switching between different API Credentials
config(['services.azure.client_id' => $company_credentials->client_id]);
config(['services.azure.client_secret' => $company_credentials->client_secret]);
config(['services.azure.redirect' => $company_credentials->client_redirect]);
session(['id' => $request['company']]);
return Socialite::with('azure')->redirect();
}
return back()->with('status', 'Please select a Valid company');
}
Now I want to convert the same code to Laravel Rest API whereby I consume it in Angular-10
I am using Laravel-Passport and LaravelSocialite as shown above.
Since I am no more using Session, how do I now deal with
session(['id' => $request['company']]);
in the code above?
Thanks

Related

Create session on consuming login with api on laravel

I have an api that has a method to start and I am calling it from a frontend project.
In the front end project I use Guzzle to make the call via post to the api and login, from which I get back a json with the user data and a jwt token.
But when I receive the token as I manage the session, I must create a session and save the token, since the laravel to authenticate I need a model user and have a database, which of course I do not have in this backend because I call the api to log in, which brings a token and user data, then as I manage it from the backend, I'm a little lost there.
$api = new Api();
$response = $api->loginapi(['user'=>'wings#test.com','password'=>'123']);
Because here I could not do Auth::login($user) to generate the session.
Because I don't have here the database because the login is done from the api.
There I call the api, of which the answer is the token, but how do I manage it from here, creating a session? saving the token?
thanks for your help.
With api, you don't usually manage a session. usually, you'd call something like
Auth::attempt([
'email' => 'me#example.com',
'password' => 'myPassword'
]);
If the credentials are correct, laravel will include a Set-Cookie header in response, and, that is how you authenticate with api. Via an auth cookie. You don't need to do anything else.
Let's show you how:
//AuthController.php
public function login(Request $request) {
$validatedData = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if(Auth::attempt($validatedData)){
return ['success' => 'true'];
}
else{
return ['success' => false, 'message' => 'Email or password Invalid'];
}
}
public function currentUser (){
return Auth::user();
}
Now, the APi file
Route::post('/login', ['App\Http\Controllers\AuthController', 'login']);
Route::get('/current_user', ['App\Http\Controllers\AuthController', 'currentUser']);
Now if you make a call to /api/current_user initially, you'll get null response since you're not currently logged in. But once you make request to /api/login and you get a successful response, you are now logged in. Now if you go to /api/current_user, you should see that you're already logged in.
Important ::
If you are using fetch, you need to include credentials if you're using something other than fetch, check out how to use credentials with that library or api
You want to use the API to authenticate and then use the SessionGuard to create session including the remember_me handling.
This is the default login controller endpoint for logging in. You don't want to change this, as it makes sure that user's do not have endless login attempts (protects for brut-force attacks) and redirects to your current location.
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
if ($request->hasSession()) {
$request->session()->put('auth.password_confirmed_at', time());
}
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
The core happens when we try to "attemptLogin" at
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->boolean('remember')
);
}
When using the SessioGurad (which is default) the method attemptLogin fires a couple of events, checks if the user has valid credentials (by hashing the password and matching it with db) and then logs the user in, including the remember me functionality.
Now, if you don't care about events, you can just check from your API if the credentials match and then use the login method from the guard. This will also handle the remember me functionality. Something like this:
protected function attemptLogin(Request $request)
{
$username = $request->input($this->username());
$password = $request->input('password');
$result = \Illuminate\Support\Facades\Http::post(env('YOUR_API_DOMAIN') . '/api/v0/login' , [
'username' => $username,
'password' => $password
])->json();
if(empty($result['success'])){
return false;
}
// Maybe you need to create the user here if the login is for the first time?
$user = User::where('username', '=', $username)->first();
$this->guard()->login(
$user, $request->boolean('remember')
);
return true;
}

Laravel - Pusher Authentication - Server Side

I'm working on an chat application with 2 components: a client side that is a mobile app and a server side that is developed with Laravel. Currently I can't seem to figure out how to do the pusher authentication side on the server for a user on a specific channel. After figuring the documentation I found that the authentication is done via js call from the frontend with the socket-id but for my application I need to do the authentication from the server because I'm keeping a history of the messages in a local DB. What I don't find is how can I do this on the server.
The code I use for authentication is just authenticating the client on db based on a key I created in the channel enrol:
public function authorizeUser(Request $request, $groupId, $conversationId) {
/*
$socket_id = $request->get('socket_id');
*/
$user = Auth::user();
$conversation = Conversation::find($conversationId)->where('group_id', $groupId)->first();
$user_conversation = DB::table('user_conversation')
->where('conversation_id', $conversation->id)
->where('user_id', $user->id)
->first();
if($user_conversation->authorized) {
return response()->json(['response' => 'You are authorized!'], 201);
}
$accessToken = Crypt::decryptString($request->get('key'));
//dd($conversation->access_token.' '.$accessToken);
if(Hash::check($accessToken, $conversation->access_token)) {
$conversation->users()
->wherePivot('authorized', false)
->updateExistingPivot($user->id,[
'authorized' => true
]);
// Some how, here I should authorize the user for pusher
return response()->json(['response' => 'You have been authorized!'], 201);
}
}
The documentation states that I should use the routes/channels.php file to authenticate the users but from the server side I can't use Laravel Echo for creating a connection. This is done automatically from the broadcast.php file where I have set the env for the pusher.
Thank you,
Armand

Laravel login from external system

I'm developing a module with Laravel 5 inside an external system, the external system has its own login and data in another DB, then I had to implement permissions into my Laravel module, so I had to configure a Middleware in the routes, and now i get 2 login screens, I just need to log into Laravel using the external system, i created the same credentials in laravel's user table, so i want to check external username against laravel username, get the password and auto-login into laravel.
where to do this is the main problem i face.
I need this screen to autologin
Routes middleware:
Route::group(['middleware' => ['role:admin,access_backend']], function(){
Route::get('dashboard', 'dashboardController#dashboard');
.....
.....
I Get username from external system using guzzle
$client = new Client(); //GuzzleHttp\Client
$result = $client->get($url);
$body = (string)$result->getBody();
this is what i'm trying in role middleware:(guess it fails with the password hash , i always get the login screen)
$resp = User::select('username','password')->where('username',trim($body))->first();
$password = (bcrypt($resp->password));
if (Auth::attempt(['username' =>$resp->username, 'password' => $password])){
dd('Hello world');
return redirect()->intended('dashboard');
/* ->route('admin/dashboard')
->with('Welcome! Your account has been successfully created!'); */
}
if (Auth::guest()) {
return redirect(url(config('backpack.base.route_prefix').'/login'));
}

Laravel Stormpath not able to access User Object

I am using Laravel and Stormpath for User Management. I am able to register and login user successfully using AJAX.
After successful login only the url is returned to AJAX, but after login when I go to User specific pages I am not able to fetch User Data.
Registration and Login happens in RegisterController
User Pages are rendered using UserController
I've tried to get User data using
$user = app('stormpath.user');
in UserController, but when I do dd($user) null is returned.
How to persist or get User Data after successful login or sign-up in other Controllers?
Any help appreciated! Thanks in advance!
For the Stormpath Laravel integration, when you run AJAX calls, we do not set any cookies. We provide you with the JWT in the header response that you will need to look at and then store them youself. The JWT will then need to be attached to all other requests as a Bearer token which will allow you to use the `$user = app('stormpath.user') method to get the user information out of the JWT.
I finally got everything working. Thank you #bretterer
// Stormpath user account creation
\Stormpath\Client::$apiKeyProperties = "apiKey.id="
.env('STORMPATH_CLIENT_APIKEY_ID').
"\napiKey.secret=".env('STORMPATH_CLIENT_APIKEY_SECRET');
$client = \Stormpath\Client::getInstance();
$apps = $client->tenant->applications;
$apps->search = array('name' => 'My Application');
$application = $apps->getIterator()->current();
$account = \Stormpath\Resource\Account::instantiate(
[
'givenName' => $request->input('username'),
'middleName' => '',
'surname' => 'StromTrooper',
'username' => $request->input('username'),
'email' => $request->input('user_mail'),
'password' => $request->input('user_pass'),
'confirmPassword' => $request->input('user_pass')
]
);
// Create User Account and Log-in the User
try
{
$response = $application->createAccount($account);
$passwordGrant = new \Stormpath\Oauth\PasswordGrantRequest(
$request->input('user_mail'),
$request->input('user_pass')
);
$auth = new \Stormpath\Oauth\PasswordGrantAuthenticator($application);
$result = $auth->authenticate($passwordGrant);
$atoken = cookie("access_token",
$result->getAccessTokenString(),
$result->getExpiresIn()
);
$rtoken = cookie("refresh_token",
$result->getRefreshTokenString(),
$result->getExpiresIn()
);
$response_bag['success'] = url('userprofile');
}
catch (\Stormpath\Resource\ResourceError $re)
{
$response_bag['error'] = $re->getMessage();
$atoken = 'null';
$rtoken = 'null';
}
return response()
->json($response_bag)
->withCookie($atoken)
->withCookie($rtoken);
and in the User controller I am able to access the user details using app('stormpath.user');
and since I was using Laravel 5.1
I had to comment out $token = $request->bearerToken(); from vendor/stormpath/laravel/src/Http/Middleware/Authenticate.php from function public function isAuthenticated(Request $request)

Returning Token to Store in Local Storage / Cookie On Login Page Reroute - Laravel 4.2

I have a Laravel app that currently uses the built-in authentication system to determine who is logged in or not logged in. The built-in authentication uses a session based system. I am transitioning to a custom authentication system that uses random tokens stored either in local storage or cookies to determine user identity.
I am currently using the following:
public function auth{
$user = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'active' => 1
);
if(Auth::attempt($user, true)){
$userId = Auth::id();
$salt = $customGenerator->generateSalt();
$userToken = $customGenerator->generateTokenAndSaveInDB($userId, $salt);
// Can I also sent $userToken to index.welcome to store in localStorage?
return Redirect::route('index.welcome');
}
else{
return Redirect::route('index.failed');
}
}
The above will redirect the user to a specific page if their credentials were valid. I would also like to have $userToken be sent to this new page so I can store it in the client's local storage.
Is this possible with Laravel?
can you try
return Redirect::route('index.welcome', array('userToken' => $userToken));
Laravel Forum

Resources