I've got same login page for every CRM.
These are the steps:
Enter password and login
Send curl to CRM on crm.dev/api/auth/check with user data, which checks if user exists in CRM
CRM returns success if user exists, after this authenticates user via Auth::user('user_data_here') and redirects to main page of CRM
My problem is that auth doesn't work. And no user data is stored in session (because of previous problem).
CRM auth code:
public function checkUserExists(Request $request)
{
$this->redirectIfAuthorized();
$user = User::find($request->uid);
if ($user) {
return ['response' => 'LOGIN_SUCCESS'];
}
return ['response' => 'DB_ERROR'];
}
public function login(Request $request)
{
$this->validateLogin($request);
$user = User::find($request->uid);
$user->remember_token = $request->token;
if ($user->update()) {
Auth::login($user, true);
return redirect()->intended($this->redirectPath());
} else {
return redirect($this->redirectAfterLogout);
}
}
public function redirectIfAuthorized()
{
if (Auth::check()) {
return redirect($this->redirectTo);
}
}
Api route:
Route::group(['prefix' => 'auth'], function () {
Route::post('check', 'LoginController#checkUserExists');
Route::get('login', 'LoginController#login');
Route::get('logout', 'LoginController#logout');
});
And login page's logic for this CURL request
private function sendToken($action, $user, $token)
{
$query = DB::table('user_base')->join('bases', 'bases.id', '=', 'user_base.base_id')
->where('user_base.user_id', $user);
$result = $query->get();
foreach ($result as $row) {
$urlAPI = $row->url_api;
if ($urlAPI == 'http://appliance.dev/api/auth') {
$urlAPI .= '/check';
}
$rsp = $this->curl($urlAPI, array(
'apiKey' => $this->apiKey,
$action => true,
'uid' => $row->base_uid,
'token' => $token
));
}
}
I needed to use routing in web.php file instead of api.php
Related
I'm trying to make login with google using laravel socialite and I have a problem.
Route that initiates login:
Route::get('/auth/login/google', 'AuthController#google');
Method in controller that initiates login:
public function google()
{
return Socialite::driver('google')->redirect();
}
Callback route:
Route::get('/auth/login/google/redirect', 'AuthController#googleRedirect');
Callback method in controller:
public function googleRedirect()
{
$googleUser = Socialite::driver('google')->user();
$email = $googleUser->getEmail();
$user = new User();
$user = $user->firstOrCreate(['email' => $email], ['email' => $email, 'password' =>
bcrypt(str_shuffle('abcdefgh45678')), 'email_verified' => 1]);
Auth::login($user, true);
}
And I'm getting ERR_EMPTY_RESPONSE every time I'm trying to redirect user after login.
Funny thing is that I can dump data with dd(Auth::user()->id) and I'm getting user's ID, but when I try to redirect user to the home page using return redirect('/') I'm getting empty response error and if I manually go to home page my user is not authenticated.
#Matej Petric blow code is working for me.
public function handleProviderCallback($provider) {
$user = Socialite::driver('google')->stateless()->user();
$authUser = $this->findOrCreateUser($user);
if ($authUser) {
Auth::login($authUser, true);
return redirect('/');
} else {
return redirect('/login')->withErrors(['msg', 'The Message']);
}
}
public function findOrCreateUser($user) {
$authUser = User::where('email', $user->email)->first();
if ($authUser) {
return $authUser;
}
$userN = User::create([
'name' => $user->name,
'email' => $user->email,
'password' => bcrypt(generateRandom()),
]);
return $userN;
}
I tried to make login page . By using middleware , i should able to redirect to main page when I click sign in button but when i hit sign in button , its return redirect back to my login page. Here is my code
Authenticate.php (middleware)
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
web.php (route)
Route::get('/', 'AuthController#index')->name('login');
Route::post('/login', 'AuthController#login')->middleware('auth')->name('welcome');
AuthController.php
public function index(Request $request) {
return view('auth.login');
}
public function login(Request $request)
{
$username = $request->username;
$pass = $request->password;
$password = base64_encode(sha1($pass, true));
$options = [
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'username' => $username,
'password' => $password,
]
];
$response = $this->client->post('userLogin', $options)->getBody();
$content = json_decode($response->getContents());
if($content == null)
{
return redirect()->back()->with('error', 'Username not exist');
}
return view('welcome.dashboard'); //expected redirect to dashboard after login
}
the login data was from backend api . I just pull data by using guzzle .Sorry if my explaination not clear but i hope its help and sorry for my bad english
Now when I want to log out my user, I send a post request to my API (with Bearer token)
Route::group(['middleware' => ['auth:api']], function () {
Route::post('/logout', 'UserApiController#logout');
});
UserApiController.php
public function logout(){
if (Auth::check()) {
Auth::user()->token()->revoke();
return response()->json(['success' =>'logout_success'],200);
}else{
return response()->json(['error' =>'api.something_went_wrong'], 500);
}
}
The answers here are all great. If revoke() does not work i.e
Auth::user()->token()->revoke();
does not work, use,
public function logout(Request $request)
{
$response = self::HTTP_CREATED;
$user= $request->user();
unset($user->api_token);
$user->save();
return response()->json([
'response' => 'true',
'result' => '',
'message' => 'User logged out'
], $response);
}
The goal is to remove the token from the table which the above code does manually.
Also tested with laravel 7.24, if you do not use middleware in api-routes.:
api.php
Route::post('/logout', 'LoginController#logout');
Use the api-guard (= passport) and then the standard laravel passport "revokeAccessToken" method.
public function logout ()
{
$tokenRepository = app('Laravel\Passport\TokenRepository');
$user = auth('api')->user();
if ($user) {
$tokenRepository->revokeAccessToken($user->token()->id);
return 'logged out';
} else {
return 'already logged out';
}
}
Ok so what i'm trying todo, do not let login if user has not confirmed his account by email. My login code looks like that:
public function postLogin()
{
$credentials = [
'confirmed' => 0,
'email' => Input::get('email'),
'password' => Input::get('password')
];
$user = Sentinel::authenticate($credentials, false); // Login the user (if possible)
if ($user and $user->banned) {
Sentinel::logout();
$user = null;
}
if ($user) {
return $this->afterLoginActions();
} else {
$this->alertFlash(trans('app.access_denied'));
return Redirect::to('auth/login');
}
}
But i can still login without any errors. Any help? Thanks guys!
Edited: working, but now i dont get flash message if my details are incorect.
Code:
public function postLogin()
{
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password'),
'confirmed' => 1
];
$user = Sentinel::authenticate($credentials, false); // Login the user (if possible)
if ($user and $user->banned) {
Sentinel::logout();
$this->alertFlash(trans('app.banned'));
$user = null;
}
if ($user->confirmed==1) {
return $this->afterLoginActions();
}
else if ($user->confirmed==0) {
Sentinel::logout();
$this->alertFlash(trans('app.not_active'));
return Redirect::to('auth/login');
} else {
$this->alertFlash(trans('app.access_denied'));
return Redirect::to('auth/login');
}
}
Do you have a column in your table storing the information if this user passed the email confirmation? If you have one, this is what I do it with typical Laravel postLogin method.
public function postLogin(Request $request)
{
$credentialas = (your credential here);
// only check credentials
if ($this->guard()->once($credentials)) {
$currentStatus = $this->guard()->user()->status;
if (intval($currentStatus) === (NOT_CONFIRMED)) {
$this->guard()->logout();
return $this->sendSuspendedResponse($request);
} else {
$this->guard()->login($this->guard()->user());
return $this->sendLoginResponse($request);
}
}
}
I'm using Socialite to get user information from facebook. All is going well but my redirect isn't working
Sub-routes
I read that it's not possible to do a redirect from a submethod, or
any method that's not in your routes.
But how else can i redirect the user after I logged them in?
My URL looks like this after the successfull facebook handshake
http://tmdb.app/auth/login/facebook?code=AQBTKNZIxbfdBruAJBqZ8xx9Qnz...
Code
class SocialController extends Controller {
public function login(Authenticate $authenticate, Request $request)
{
return $authenticate->execute($request->has('code'), $this);
}
public function userHasLoggedIn($data)
{
$user = User::where('provider_id', $data->id)->first();
if( !$user )
{
$user = User::create([
'name' => $data->name,
'email' => $data->email,
'provider' => 'facebook',
'provider_id' => $data->id
]);
}
// NOT WORKING!
return redirect('test');
}
}
Your login function should be handling the redirect.
I'm guessing execute returns $data if the user is sucessfully logged in and false if not.
class SocialController extends Controller {
public function login(Authenticate $authenticate, Request $request)
{
if($data = $authenticate->execute($request->has('code'), $this))
{
$user = User::where('provider_id', $data->id)->first();
// maybe delegate the user creation to another class/service?
if( !$user )
{
$user = User::create([
'name' => $data->name,
'email' => $data->email,
'provider' => 'facebook',
'provider_id' => $data->id
]);
}
return redirect('test');
}
return redirect('fail_view');
}
}
You can do it using PHP header function in Laravel sub method. I try it and works properly. Hope it can help you.
// You can using the following code
$url= url("about-laravel");
header("Location:" . $url);
exit;
// Or using the following code to redirect and keep set flash message
$result= $this->yourMethod(); // return redirect($this->route)->with('flash_message', 'I\'m Flash Message'); for TRUE or NULL for false
if( $result ){
return $result;
}