In Laravel 5.1 I used something like:
function enable(TokenRepositoryInterface $tokens)
{
// (...)
$token = $tokens->create($user);
Mail::send('emails.enabled', ['user' => $user, 'email' => $user->email, 'token' => $token], function ($m) use ($user) {
$m->to($user->email, $user->name)->subject('Welcome to ..., ' . $user->name . '!');
});
// (...)
}
to manually send a password-set token, after sign up (by abusing Laravels own password-reset tokens). However the TokenRepositoryInterface repository interface seems to be gone in Laravel 5.2.
Is there any way to manually create a password-reset token in Laravel 5.2 or do I need to manually implement that token handling for sign ups?
you can create a token using a passport in your laravel application
$user->createToken('Client Token')->accessToken;
Related
Hello i'm newbie in laravel. I use for authorization sanctum. But i want that some request can available for authorization user (i use laravel for only api, on front i use angular 2).
web.php:
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('api/user-information', function(Request $request) {
return response()->json([ auth()->user()]);
});
// API route for logout user
Route::post('api/logout', [AuthController::class, 'logout']);
});
How can I get access token after success autorization user that i can send request for middleware routes. Because if i have request withous access token i always send null in 'api/user-information'. Please help me resolve this problem.
You could better make a new function in a controller, probably the AuthController. In this function you can validate fields
$validatedData = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
With the validated data you can use Auth::login($validatedData);
Source: https://laravel.com/docs/9.x/authentication#login-throttling
Welcome to Laravel! I am assuming you have login method that authenticates user. You can create a token in that method and pass it to your frontend.
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return ['status'=>0,'message'=>'Invalid Credentials','data'=>[]];
}
$data = [
'user'=>$user,
'token'=>$user->createToken('MyToken')->plainTextToken
];
return ['status'=>1, 'message'=>'Login Successful!', 'data'=>$data];
}
If you just need to pass the token, you can simply return token in the response and then pass it in request header (Authorization) of your Angular applcation to access the API routes protected by Sanctum middleware auth:sanctum
return $user->createToken('MyToken')->plainTextToken;
Also since you are going to use Laravel for API, I would suggest you put all your routes in routes/api.php file.
The routes in routes/api.php are stateless and are assigned the api middleware group. The prefix '/api' is applied to all the routes defined in api.php
You can read more about it in Laravel Documentation
Issuing API Tokens
The Default Route Files
We have the need to login user ONLY via OpenId (exactly Microsoft Azure AD OpenId Connect).
We understand how to use Socialite but we would like to integrate with Backpack For Laravel, because app is 90% base cruds and because we already have a paid licence.
How to integrate socialite with backpack for laravel?
Also ... we should integrate it with laravel-permissions that it's very easy to integrate with backpack for laravel
If you need socialite, I recommend not using the Backpack authentication at all. Just disable everything related to authentication in your config/backpack/base.php file (the routes mainly), code your own controller logic with socialite and plug in your own auth middleware and guard within that same config file, so that Backpack uses your auth instead of the default one.
It will be easier to code and maintain your own logic, rather than mangling the default auth to work the way you want it.
This is actually a working solution
config\backpack\base.php
'guard' => null,
.env
AZURE_CLIENT_ID=0e8b592f-asaaaasd4eac-a368-d0d52dbc14e0
AZURE_CLIENT_SECRET=b2r5442
AZURE_REDIRECT_URI=/sso/callback
config\services.php
// See https://socialiteproviders.com/Microsoft-Azure/#installation-basic-usage
'azure' => [
'client_id' => env('AZURE_CLIENT_ID'),
'client_secret' => env('AZURE_CLIENT_SECRET'),
'redirect' => env('AZURE_REDIRECT_URI')
],
Packages installed:
"laravel/socialite": "^5.2",
"lcobucci/jwt": "^4.1",
"socialiteproviders/microsoft-azure": "^4.2",
routes\web.php
Route::get('/login', [\App\Http\Controllers\AuthController::class, 'login'])->name('login');
Route::get('/sso/callback', [\App\Http\Controllers\AuthController::class, 'ssoCallback']);
app/Http/Controllers/AuthController.php
use Laravel\Socialite\Facades\Socialite;
use Lcobucci\JWT\Configuration;
....
public function login()
{
return Socialite::driver('azure')->scopes(['openid'])->redirect();
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect("https://login.microsoftonline.com/common/oauth2/v2.0/logout");
}
public function ssoCallback()
{
try {
$user = Socialite::driver('azure')->user();
}
catch (\Laravel\Socialite\Two\InvalidStateException $e) {
return redirect(route('login'));
}
catch (\GuzzleHttp\Exception\ClientException $e) {
return redirect(route('login'));
}
// Read the claims from token JWT using Lcobucci\JWT package
$configuration = Configuration::forUnsecuredSigner();
$token = $configuration->parser()->parse( $user->accessTokenResponseBody["id_token"] );
$claims = $token->claims()
// This is an example, it depends by your jwt
$full_name = $user->name;
$email = $user->email;
$app_user = User::firstOrCreate([
'name' => $full_name,
'email' => $email,
]);
auth()->login($app_user);
}
I’ve two Laravel based projects and I want to login with API which the first project provides and use this authentication in the second project.
in the LoginController in second project:
public function login(Request $request)
{
$login_response = Http::post('{first_project_login_api}', [
'data' => [
"email" => $request->input('email'),
"password" => $request->input('password')
]
]);
if ($this->attemptLogin($login_response)) {
return $this->sendLoginResponse($request);
}
}
protected function attemptLogin(Response $response)
{
return $response->object()->status === 200;
}
In the second project, I don't need to database because I want to authentication in the first project but does not seems to be possible!
actually I need to know how to overwrite attemptLogin() function in LoginController.
It would be highly appreciated if anyone can advise me!😊
Instead of using login between application, i would use API keys. The easiest way to get started is to use simple API Authentication.
First create migrations for the user table.
Schema::table('users', function ($table) {
$table->string('api_token', 80)->after('password')
->unique()
->nullable()
->default(null);
});
To get keys, set them on the user either in Tinker, command or creation.
$user->api_token = Str::random(60);
$user->save();
Protect your API routes with a middleware.
Route::middleware('auth:api')->group(function() {
// your routes
});
Calling your api is as simply as.
response = $client->request('POST', $yourRoute, [
'headers' => [
'Authorization' => 'Bearer ' . $yourToken,
'Accept' => 'application/json',
],
]);
This is a fairly basic setup, for production or moving forward you should look into Sanctum or Passport. This is just a good start, from where i feel you are based on your question.
In a laravel 5.8 API project, I want users to login via their social accounts. So far I have been able to use Socialite to retrieve user info from the provider and use it to create a new user record. But when I try to have the user log in again, it throws up the following error
Call to undefined method Laravel\Socialite\Two\User::createToken()
Here's the code I am working with
<?php
namespace App\Http\Controllers;
use App\User;
use Socialite;
use App\SocialAccount;
use App\Http\Resources\UserResource;
class SocialAuthController extends Controller
{
...
public function handleProviderCallback($provider)
{
$socialUser = Socialite::driver($provider)->stateless()->user();
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
/*
if account exist, return the social account user
else create the user account, then return the new user
*/
if ($userSocialAccount) {
// generate access token for use
$token = $socialUser->createToken('********')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($userSocialAccount))
]);
} else {
$user = User::create([
'firstname' => $socialUser->name,
'lastname' => $socialUser->name,
'username' => $socialUser->email,
'email_verified_at' => now()
]);
if ($user) {
SocialAccount::create([
'provider_id' => $socialUser->id,
'provider_name' => $provider,
'user_id' => $user->id
]);
}
// assign passport token to user
$token = $user->createToken('********')->accessToken;
return response()->json(['token' => $token, 'user' => new UserResource($user)]);
}
}
}
I haven't been able to spot the reason why I am getting the error when the user attempts a second login but there is no error if it's the first time the user logs in with a social account.
Why does it complain about Laravel\Socialite\Two\User::createToken() method? If I try adding this line use Laravel\Socialite\Two\User vscode intelephsense flags it as a duplicate of App\User so what is really going on in my code?
I think your last sentence hits the problem: the Laravel\Socialite\Two\User and App\User are two fully separate entities.
The Socialite::driver($provider)->stateless()->user() provides you with a Socialite User whereas User::create creates an App\User.
The second $token = $user->createToken('********')->accessToken; works because App\User has the createToken function and the other does not.
First of all the problem I was having with having a token generated by passport for users authentication after the first social login was because I was calling the createToken method on the user returned by Socialite. As explained by #JorisJ1 Socialite does not have the createToken function so my initial code threw an error.
Here's how I fixed it
public function handleProviderCallback($provider)
{
// retrieve social user info
$socialUser = Socialite::driver($provider)->stateless()->user();
// check if social user provider record is stored
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
if ($userSocialAccount) {
// retrieve the user from users store
$user = User::find($userSocialAccount->user_id);
// assign access token to user
$token = $user->createToken('Pramopro')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($user))
]);
} else {
...
}
}
Comments are welcomed if there is a better way for adding social authentication to API.
I know how the basic auth works for sign up/login on Laravel. However, I want to learn setting up how to do user sign up (for Password Grant). I set up Passport (2.0) - Passport Grant, and I can get token; however I couldn't find anything for user signup. Then I found a topic here explaining that I should call the oauth/token internally, but also couldn't figure out how to achieve it exactly.
So what I thought is creating a signup() method in a controller and handle user registration on my own, but then how would I pass necessary data to oauth/token route? Because what Laravel uses for $request is Request $request but what Passport uses is ServerRequestInterface $request and when I vardump the $request on oauth/token's issueToken method, it's totally different Request $request.
// Setup new method
public function signup(Request $request) {
// do validations
// create user
User::create([
'email' => $request->username,
'password' => bcrypt($request->password),
]);
$client = \Laravel\Passport\Client::where('password_client', 1)->first();
$oauthData = [
'grant_type' => 'password',
'client_id' => $client->id,
'client_secret' => $client->secret,
'username' => $request->email,
'password' => $request->password,
'scope' => null
]
// Here, I got confused how to pass this `oauthData` to `issueToken()` route
// and it takes it as `ServerRequestInterface $request`
}
Someone did it likes this here, but no idea how I should exactly implement this approach. Because my /oauth/token route's post method issueToken() is like this:
public function issueToken(ServerRequestInterface $request)
{
return $this->withErrorHandling(function () use ($request) {
return $this->server->respondToAccessTokenRequest($request, new Psr7Response);
});
}
I am very confused and couldn't figure out how to overcome this. What is the right way of handling such scenario where I need to signup users through api?