if the email and username is incorrect it redirects to /login. And if i am successfully logged in, it donot redirect to /crud.
public function authenticate(Request $request)
{
$password=$request->get('password');
$email=$request->get('email');
if (Auth::attempt(['email' => $email, 'password' => $password]) )
{
return redirect()->intended('/crud');
}
else
{
return redirect('/crud/login');
}
}
but then again if i am logged in this function below shows me logged in.
public function check()
{
if (Auth::check())
{
print_r('logged in');
}
else
{
print_r('not logged in');
}
}
this is how i protected /crud
Route::group(['middleware' => ['auth','web']], function () {
Route::get('/crud','CrudController#index');
});
Related
web.php
Route::get('/', [AdminLoginController::class, 'index'])->name('admin.login');
Route::post('/login', [AdminLoginController::class, 'login'])->name('admin.login.submit');
Route::group(['middleware' => 'admin.middle' ] , function() {
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('admin.dashboard');
});
AdminLoginController.php
public function login(Request $request)
{
$validator = Validator::make($request->all(),[
'email' => 'required|email:rfc,dns|exists:admins,email',
'password' => 'required',
],[
'email.required' => "Email is required",
'email.email' => "Email is invlaid",
'email.exists' => "Email does not exist",
'password.required' => "Password is required"
]);
if($validator->fails())
{
$this->sendResponse(400,$validator->errors()->first(),[]);
}
else
{
if (Auth::guard('admin')->attempt(["email" => $request->email , "password" => $request->password])) {
$this->sendResponse(
200,
"Successfully Logged In",
[
'location' => route('admin.dashboard')
]);
}
else {
$this->sendResponse(
500,
"Email or Password is incorrect",
[]);
}
}
}
AdminAuthenticate.php
class AdminAuthentication
{
public function handle(Request $request, Closure $next)
{
if (Auth::guard('admin')->check())
{
if (Auth::guard('admin')->user()){
return $next($request);
}
}
return redirect('/admin');
}
}
Maybe your sendResponse is not set corresponding headers (Set-cookie)? It looks like you mixing api responses with responses for browser.
I'm trying to use the default <'LoginButton ... > for login in the app through Facebook login, but I can't manage to get the user's email.
This is my button:
<LoginButton
publishPermissions={["email"]}
onLoginFinished={
(error, result) => {
if (error) {
alert("Login failed with error: " + error.message);
} else if (result.isCancelled) {
alert("Login was cancelled");
} else {
alert("Login was successful with permissions: " + result.grantedPermissions)
}
}
}
onLogoutFinished={() => alert("User logged out")}
/>
And this is how i try to get the user's details:
async FBGraphRequest(fields, callback) {
const accessData = await AccessToken.getCurrentAccessToken();
console.log("token= ", accessData.accessToken )
// Create a graph request asking for user information
const infoRequest = new GraphRequest('/me', {
accessToken: accessData.accessToken,
parameters: {
fields: {
string: fields
}
}
}, this.FBLoginCallback.bind(this));
// Execute the graph request created above
new GraphRequestManager().addRequest(infoRequest).start();
}
async FBLoginCallback(error, result) {
if (error) {
this.setState({
showLoadingModal: false,
notificationMessage: "facebook error"
});
} else {
// Retrieve and save user details in state. In our case with
// Redux and custom action saveUser
this.setState({
id: result.id,
email: result.email,
name: result.name
});
console.log("facebook login",result)
}
}
The console.log("facebook login",result) line returns me only the account name and id, but there is no field for te email...
What am I doing wrong?
PS.: I've also tryed to use a "custom function", but it doesn't work too (for the email, the login worked and i get only the user details like name and id):
async facebookLogin() {
// native_only config will fail in the case that the user has
// not installed in his device the Facebook app. In this case we
// need to go for webview.
let result;
try {
this.setState({showLoadingModal: true});
LoginManager.setLoginBehavior('NATIVE_ONLY');
result = await LoginManager.logInWithReadPermissions(['public_profile', 'email']);
} catch (nativeError) {
try {
LoginManager.setLoginBehavior('WEB_ONLY');
result = await LoginManager.logInWithReadPermissions(['email']);
} catch (webError) {
// show error message to the user if none of the FB screens
// did not open
}
}
console.log("facebook result 1: ", result)
// handle the case that users clicks cancel button in Login view
if (result.isCancelled) {
this.setState({
showLoadingModal: false,
notificationMessage: I18n.t('welcome.FACEBOOK_CANCEL_LOGIN')
});
} else {
// Create a graph request asking for user information
this.FBGraphRequest('id, email, name', this.FBLoginCallback);
}
}
.
.
.
<LoginButton
publishPermissions={["email"]}
onPress={
this.facebookLogin()
}
onLogoutFinished={() => alert("User logged out")}
/>
this are the field request by the app. I need to insert also the user's Email:
!!!RESOLVED!!!
the <'LoginButton ...> props for the permission is "permissions", not "readPermission"...
so the button code is:
<LoginButton
permissions={['public_profile', 'email', 'user_birthday', ]}
onClick={this.facebookLogin}
/>
// imports
import {
Settings,
AccessToken,
LoginManager,
AuthenticationToken,
Profile,
GraphRequest,
GraphRequestManager,
} from 'react-native-fbsdk-next';
//put this lines in useEffect
Settings.setAppID('2920461228193006');
Settings.initializeSDK();
LoginManager.setLoginBehavior('web_only');
// put this method on button press
LoginManager.logInWithPermissions(['public_profile', 'email'])
.then(async data => {
if (!data.isCancelled) {
console.log(data, 'this is data');
if (Platform.OS === 'ios') {
let token =
await AuthenticationToken.getAuthenticationTokenIOS();
console.log(token, 'ios token');
} else {
let token = await AccessToken.getCurrentAccessToken();
console.log(token, 'android token');
}
const infoRequest = new GraphRequest(
'/me?fields=email,name,first_name,last_name',
null,
(err, res) => {
console.log({err, res}, 'this is');
if (Object.keys(res).length != 0) {
doSocialLogin({
registerBy: 2,
token: res.id,
user: {
firstName: res.first_name,
email: res.email,
lastName: res.last_name,
},
});
}
},
);
new GraphRequestManager().addRequest(infoRequest).start();
}
})
.catch(err => {
console.log(err, 'this is fb error');
});
I am working on a SPA, I have used JWT authentication for a login system. on the local server its working fine, I mean when I click login I get the token etc and store on local storage and it redirects me to dashboard everything perfect.
but on a live server, I get the token but it doesn't store it on local storage.
I am completely lost. I tried everything but still. please help me with this.
it's my first time with the SPA so I am not sure what I am missing.
Login Method
login(){
User.login(this.form)
}
User.js
import Token from './Token'
import AppStorage from './AppStorage'
class User {
login(data) {
axios.post('/api/auth/login', data)
.then(res => this.responseAfterLogin(res))
.catch(error => console.log(error.response.data))
}
responseAfterLogin(res) {
const access_token = res.data.access_token
const username = res.data.user
if (Token.isValid(access_token)) {
AppStorage.store(username, access_token)
window.location = '/me/dashboard'
}
}
hasToken() {
const storedToken = AppStorage.getToken();
if (storedToken) {
return Token.isValid(storedToken) ? true : this.logout()
}
return false
}
loggedIn() {
return this.hasToken()
}
logout() {
AppStorage.clear()
window.location = '/me/login'
}
name() {
if (this.loggedIn()) {
return AppStorage.getUser()
}
}
id() {
if (this.loggedIn()) {
const payload = Token.payload(AppStorage.getToken())
return payload.sub
}
}
own(id) {
return this.id() == id
}
admin() {
return this.id() == 1
}
}
export default User = new User();
Token.js
class Token {
isValid(token){
const payload = this.payload(token);
if(payload){
return payload.iss == "http://127.0.0.1:8000/api/auth/login" ? true : false
}
return false
}
payload(token){
const payload = token.split('.')[1]
return this.decode(payload)
}
decode(payload){
return JSON.parse(atob(payload))
}
}
export default Token = new Token();
AppStorage.js
class AppStorage {
storeToken (token) {
localStorage.setItem('token', token);
}
storeUser (user) {
localStorage.setItem('user', user);
}
store (user, token) {
this.storeToken(token)
this.storeUser(user)
}
clear () {
localStorage.removeItem('token')
localStorage.removeItem('user')
}
getToken () {
return localStorage.getItem('token')
}
getUser () {
return localStorage.getItem('user')
}
}
export default AppStorage = new AppStorage()
Thanks
I tried implementing this tutorial on how to add an authentication process to a MEAN app:
http://mherman.org/blog/2015/07/02/handling-user-authentication-with-the-mean-stack/#.VgUaT_mqpBc
The change i tried to implement is to make the app a single page app ... so the only routes i left were the post routes for login ... i am addressing the login because if i can make that work ... the rest will follow
So my app consists of a google map that fills the page and two buttons (login and register) that open a modal window ... inside i have login form ... here are the codes for the angular controller of the modal window and the jade template
Controller:
angular.module('myApp')
.controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'settings', '$location', 'AuthService', function ($scope, $modalInstance, settings, $location, AuthService) {
$scope.settings = settings;
$scope.texts = {
login: {
title: "Login details",
button: "Login"
},
register: {
title: "Registration form",
button: "Register"
}
};
$scope.register = function () {
$modalInstance.close();
};
$scope.login = function () {
// initial values
$scope.error = false;
// call login from service
AuthService.login($scope.loginForm.username, $scope.loginForm.password)
// handle success
.then(function () {
console.log(AuthService.getUserStatus());
$modalInstance.close();
})
// handle error
.catch(function () {
$scope.error = true;
$scope.errorMessage = "Invalid username and/or password";
});
//$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.close();
};
}])
Jade template for modal window:
div(class="modal-header")
h3(class="modal-title") {{texts[settings.action].title}}
div(class="modal-body")
div(ng-show="error", class="alert alert-danger")
form(class="form", ng-submit="login()")
div(class="form-group")
label Username
input(type="text", class="form-control", name="username", ng-model="loginForm.username")
div(class="form-group")
label Password
input(type="password", class="form-control", name="password", ng-model="loginForm.password")
div(class="modal-footer")
button(ng-show="settings.action=='login'", class="btn btn-primary", type="button", ng-click="login()") {{texts.login.button}}
button(ng-show="settings.action=='register'", class="btn btn-primary", type="button", ng-click="register()") {{texts.register.button}}
button(class="btn btn-warning", type="button", ng-click="cancel()") Cancel
So my pb is this: the passport authenticate gets executed correctly .. I get the login success message ... but on refresh ... if I run AuthService.isLoggedIn() .. I get false ...
Here is the service:
angular.module('myApp').factory('AuthService',
['$q', '$timeout', '$http',
function ($q, $timeout, $http) {
// create user variable
var user = null;
// return available functions for use in controllers
return ({
isLoggedIn: isLoggedIn,
getUserStatus: getUserStatus,
login: login,
logout: logout,
register: register
});
function isLoggedIn() {
if(user) {
return true;
} else {
return false;
}
}
function getUserStatus() {
return user;
}
function login(username, password) {
// create a new instance of deferred
var deferred = $q.defer();
// send a post request to the server
$http.post('/user/login', {username: username, password: password})
// handle success
.success(function (data, status) {
if(status === 200 && data.status){
user = true;
deferred.resolve();
} else {
user = false;
deferred.reject();
}
})
// handle error
.error(function (data) {
user = false;
deferred.reject();
});
// return promise object
return deferred.promise;
}
}]);
Here is the post route for the passport.authenticate
router.post('/login', function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err)
}
if (!user) {
return res.status(401).json({err: info})
}
req.logIn(user, function (err) {
if (err) {
return res.status(500).json({err: 'Could not log in user'})
}
res.status(200).json({status: 'Login successful!'})
});
})(req, res, next);
});
My auth component works great except it duplicates the folder that my CakePHP lives in. For example, my entire CakePHP install is in localhost/rh/ but when login redirects it sends the user to localhost/rh/rh/controller. Any thoughts?
AppController:
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'index'),
'authError' => "You are not authorized to access that page",
'authorize' => array('Controller')
)
);
public function isAuthorized($user) {
return true;
}
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
}
UserController:
class UsersController extends AppController {
//before filter to allow users to register
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add'); // Letting users register themselves
}
//login action
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
//logout action
public function logout() {
$this->redirect($this->Auth->logout());
}
Add parent::beforeFilter(); to beforeFilter in the user controller:
function beforeFilter() {
$this->Auth->autoRedirect = false;
parent::beforeFilter();
}
You can also replace the redirect with this to the login method of your user controller:
$this->redirect($this->Auth->redirect());
Auth->redirect() returns
for more clear idea just go to cakephp.org link
Add parent::beforeFilter(); to beforeFilter in the user controller:
function beforeFilter()
{
$this->Auth->autoRedirect = false;
parent::beforeFilter();
}
You can also replace the redirect with this to the login method of your user controller:
dd parent::beforeFilter(); to beforeFilter in the user controller:
function beforeFilter()
{
$this->Auth->autoRedirect = false;
parent::beforeFilter();
}
You can also replace the redirect with this to the login method of your user controller:
$this->redirect($this->Auth->redirect());
Auth->redirect() returns the url where the user landed before being taken to the login page or Auth->loginRedirect.
There is an option in the Auth component called 'unauthorizedRedirect', which is the url Cake redirects users to when they try to access a page they aren't allowed access to. If this is not set then Cake redirects to /{app-directory}, hence the appearance of your domain name where the controller should be.
Change this in your AppController
public $components = array(
//your other components
'Auth' => array(
//your other options for Auth
'unauthorizedRedirect' => 'url to redirect to' //can be in any form that Cake accepts urls in
)
);