is it possible to create an email only authentication from existing email-password structure in Laravel - mysql

I am trying to create email only authentication. Instead of having a login, I want a situation where I will only have signup and once the email is entered, a bearer token is created.
I have the signup function and login function which worked when I had password initiated but I have removed the password but I tried to move the "create token" to signup. It gives error that token is undefined.
Signup function
public function signup(Request $request)
{
$request->validate([
'email' => 'required|string|email|unique:users'
]);
$user = new User([
'email' => $request->email
]);
$user->save();
return response()->json([
'message' => 'Successfully created user!'
], 201);
}
Login function
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email'
]);
$credentials = request(['email', '=']);
if(!Auth::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse(
$tokenResult->token->expires_at
)->toDateTimeString()
]);
}

It is really simple, you have already done most of the work needed to be done here. You don't need the login function rather you need to copy the token part of the function as illustrated below
public function signup(Request $request)
{
$request->validate([
'email' => 'required|string|email|unique:users'
]);
$user = new User([
'email' => $request->email
]);
$user->save();
Auth::login($user);
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'message' => 'Successfully created user!',
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse(
$tokenResult->token->expires_at
)->toDateTimeString()
], 201);
}

Related

CakePHP 3 basic authentication get authenticated user

public function beforeSave(Event $event) //for api
{
$hasher = new DefaultPasswordHasher();
$entity->api_key_plain =
Security::hash(Security::randomBytes(32), 'sha256', false);
$entity->api_key = $hasher->hash($entity->api_key_plain);
return true;
}
$this->loadComponent('Auth', [
'authenticate' => [
'Basic' => [
'fields' => ['username' => 'username', 'password' => 'api_key'],
//'finder'=>'apiauth',
'userModel'=>'Students',
],
],
'userModel'=>'Students',
'storage' => 'Memory',
'unauthorizedRedirect' => false,
]);
public function getuser(){
$user=$this->Auth->getUser(); // Auth getUser not found
$header= $this->request->getHeader('Authorization');
$usr =$this->Auth->user(); // Always return null
return $this->jsonResponse($usr,200);
}
how to get authenticated user information form each request in CakePHP 3 AuthComponent
documentation : the getUser() method should return an array of user information on the success or false on failure.

laravel 8 API : how return user_id in store method with authentication?

i'm building an API with laravel 8 ,
i have a Post table that has this columns :
id
category_id user_id title body picture study_time likes tags
i want when a user that has admin or author level, and logged in admin panel , can add a post and in form , i show his/her username and i don't want they changed this field(user_id).
and i don't know is it possible return it with JSON response or not?
how can i do that ??
my PostController :
public function store(Request $request )
{
$data = $request->all();
$validator = Validator::make($data, [
'category_id'=>'required',
'title' => 'required|max:100|unique:categories',
'body'=>'required',
'picture'=>'required',
'study_time'=>'required',
'likes'=>'required',
'tags'=>'null|string',
]);
if ($validator->fails()) {
return response(['error' => $validator->errors(), 'Validation Error']);
}
$tags = explode(",", $request->tags);
$post = Post::create($data);
$post->tag($tags);
return response()->json([
'data' => $post,
'message' => 'xxx'
], 201);
}
return response()->json([
'data' => $post,
'message' => 'xxx'
], 201);

Checking existing record based on two fields

I am trying to insert some record by checking if certain conditions are met. What I am planning to do is to restrict the users from voting twice daily. I am using email and date as parameters.
public function store(Request $request)
{
$this->validate($request, [
'flavour' => 'required|string',
'email' => 'required|email',
'lastname'=> 'required|string',
'firstname' => 'required|string'
]);
$vote = new Vote();
//$currentDate = Carbon::now()->toDateString();
$today = Carbon::now()->format('Y-M-D');
$dup = Vote::where(['email' => $request->email, 'created_at' => $today ])->get();
if (!$dup)
{
$vote->firstname = $request->firstname;
$vote->lastname = $request->lastname;
$vote->email = $request->email;
$vote->flavour = $request->flavour;
$vote->voter_ip = $request->ip();
}
else {
return response()->json([
'message' => 'You have voted today, please wait till another day!'
]);
}
if (auth()->user()->votes()->save($vote))
return response()->json([
'success' => true,
'data' => $vote->toArray()
]);
else
return response()->json([
'success' => false,
'message' => 'Vote could not be added'
], 500);
}
The problem I am encountering now is, it doesn't take any record as it keeps displaying the message "You have voted today, please wait till another day", even if I insert a new email and/or a current user with different emails.
First, I had to create a field in my migration called "voted_at" and rearranged the code to check for the existing record based on the voted_at and email of the user
public function store(Request $request)
{
$this->validate($request, [
'flavour' => 'required|string',
'email' => 'required|email',
'lastname'=> 'required|string',
'firstname' => 'required|string'
]);
$today = Carbon::now()->toDateString();
$dup = Vote::where(['email' => $request->email, 'voted_at' => $today ])->exists();
if ($dup){
return response()->json([
'data' => $dup,
'message' => 'You have voted today, please wait till another day!'
]);
}
else {
$vote = new Vote();
$vote->firstname = $request->firstname;
$vote->lastname = $request->lastname;
$vote->email = $request->email;
$vote->flavour = $request->flavour;
$vote->voter_ip = $request->ip();
$vote->voted_at = $today;
if (auth()->user()->votes()->save($vote))
return response()->json([
'success' => true,
'data' => $vote->toArray()
]);
else
return response()->json([
'success' => false,
'message' => 'Vote could not be added'
], 500);
}
}
Thanks

Undefined index: password with JWTAuth

hello I have a problem with the password field to create a user in laravel for a restfullapi
public function store(Request $request)
{
$this->validate($request,[
'user_names' => 'required||string|max:45',
'user_lastnames' => 'required|string|max:45',
'user_email' => 'required|string|email|unique:users,user_email|max:150',
'user_password' => 'required|string|min:6|confirmed',
'user_password_confirmation' => 'required|min:6',
'user_gender' => 'required',
'user_celphone' => 'required|numeric',
'user_origin_country' => 'required|string|max:100',
]);
$user_names = $request->input('user_names');
$user_lastnames = $request->input('user_lastnames');
$user_email = $request->input('user_email');
$user_password = $request->input('user_password');
$user_password_confirmation = $request->input('user_password_confirmation');
$user_gender = $request->input('user_gender');
$user_celphone = $request->input('user_celphone');
$user_origin_country = $request->input('user_origin_country');
$user = new User([
'user_names' => $user_names,
'user_lastnames' => $user_lastnames,
'user_email' => $user_email,
'user_password' => bcrypt($user_password),
'user_gender' => $user_gender,
'user_celphone' => $user_celphone,
'user_origin_country' => $user_origin_country
]);
$credentials = [
'user_email' => $user_email,
'user_password' => $user_password
];
if ($user->save()) {
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'error' => 'El email ó la contraseña son incorrectos'
],404);
}
} catch (JWTAuthException $e) {
return response()->json([
'error' => 'failed_to_create_token',
],404);
}
$user->signin = [
'href' => 'api/v1/user/signin',
'method' => 'POST',
'params' => 'user_email, user_password'
];
$response = [
'success' => 'Usuario creado exitosamente',
'Usuario' => $user,
'token' => $token
];
return response()->json($response, 201);
}
$response = [
'error' => 'Ha ocurrido un error'
];
return response()->json($response,404);
}
I'm testing the application with postman and he tells me this
postman's picture
I have verified the routes and it works, before placing the jwt I saved the data in the db without password problems, thanks in advance

How to use JWT in Yii2 project?

In my REST API i want to use JWT fro Authorization.
So, I include this extension - https://github.com/sizeg/yii2-jwt
It clear how to create JWT token, but how to validate Token in API side ? I heart, i must use two tokens - auth_token and refresh_token. For what? What different when i whatt to validate and check user ?
I mean - ok, when i receive username and password, I create auth_token (JWT) and update token in users DB, after i return token to frontend.
After frontend will send auth token in each request, and I will validate token and check user in users DB and check access etc. How to realize refresh token and for what?
For example my controller:
class UploadController extends Controller {
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => JwtHttpBearerAuth::className()
];
return $behaviors;
}
public function actionIndex() {
//Work with User
}
}
And how to get token from headers ?
Controller
public function actionLogin()
{
$username = Yii::$app->request->post('username');
$password = Yii::$app->request->post('password');
$provider = new ActiveDataProvider([
'query' => User::find()
->where(['user_name' => $username])->asArray()->one(),
]);
$result = $provider->query;
if($result)
{
if (Yii::$app->getSecurity()->validatePassword($password, $result['user_pass']))
{
$tokenId = base64_encode(mcrypt_create_iv(32));
$issuedAt = time();
$notBefore = $issuedAt; //Adding 10 seconds
$expire = $notBefore + 5184000; // Adding 60 Days
$serverName = 'your-site.com';
$data = [
'iat' => $issuedAt, // Issued at: time when the token was generated
'jti' => $tokenId, // Json Token Id: an unique identifier for the token
'iss' => $serverName, // Issuer
'nbf' => $notBefore, // Not before
'exp' => $expire, // Expire
'data' => [ // Data related to the signer user
'id' => $result['user_id'],
'username' => $result['user_name'],
'mobile' => $result['user_mobile'],
'email' => $result['user_email'],
'city' => $result['user_city'],
'state' => $result['user_state'],
'country' => $result['user_country'],
'picture' => $result['user_picture'],
]
];
$jwt = JWT::encode(
$data,
JWT_KEY,
'HS512'
);
$response = [
'status' => true,
'message' => 'Login Success..',
'era_tkn' => $jwt,
];
}
else
{
$response = [
'status' => false,
'message' => 'Wrong username or password.',
];
}
}
else
{
$response = [
'status' => false,
'message' => 'Wrong username or password.',
];
}
return $response;
}
Make global method for check token
public function check_token()
{
$headers = Yii::$app->request->headers;
$token = $headers->get('era_tkn');
if($token)
{
try{
$valid_data = JWT::decode($token, JWT_KEY, array('HS512'));
$valid_data = $valid_data->data;
}catch(Exception $e){
$valid_data = $e->getMessage();
}
}
else
{
$valid_data = 'Required Authentication';
}
return $valid_data;
}
Call check_token mathod
$user_data = $this->check_token();
if (!empty($user_data->id))
{
echo $user_data->id;
}
else
{
echo "Invalid Token.";
}