I am getting started with lumen.
this is my web.php file
$router->group(['prefix' => 'api'], function () use ($router) {
$router->post('user', ['uses' => 'UserController#createUser']);
});
and this is my UserController.php
public function createUser(Request $request){
$this->validate($request, [
'username' => 'required',
'password' => 'required|min:3'
]);
$user = [
'username' => $request->username,
'password' => app('hash')->make($request->password),
'email' => $request->email,
'api_token' => 'asdfasd' //want should I put here
];
$user = User::create($user);
return response()->json($user, 201);
}
How do I create a new api token for that a new user who is registering?
Related
I am using Laravel7, Passport package, and Default Auth Controllers. on Web, Login and registration are working fine but on api its generating error.
Api.php
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', 'Auth\LoginController#login');
Route::post('register', 'Auth\RegisterController#create');
Route::group(['middleware' => 'auth:api'], function() {
Route::get('logout', 'AuthController#logout');
Route::get('user', 'AuthController#user');
});
});
RegisterController.php ( Inside in default Auth folder)
protected function create(array $data)
{
return User::create([
'first_name' => $data['name'],
'last_name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'phone' => $data['phone'],
'user_type'=> "abc",
]);
}
Api URL is http://127.0.0.1:8000/api/auth/register
try this -
protected function create(array $data)
{
return json_encode(User::create([
'first_name' => $data['name'],
'last_name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'phone' => $data['phone'],
'user_type'=> "abc",
])->toArray());
}
I defined my route but it is not showing that Route [dealer] not defined.
Route::resource('/dealer', DealerController::class);
This is my controller where there is index, create and store method is in same page.
public function index()
{
$users = User::all();
return view('dealer', compact('users'));
}
public function create()
{
$dealers = Dealer::all();
return view('dealer', compact('dealers'));
}
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required',
'password' => 'required',
'name_of_firm' => 'required',
'address' => 'required',
'number' => 'required',
]);
$user = User::create([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => Hash::make($request->input('password')),
'name_of_firm' => $request->input('name_of_firm'),
'address' => $request->input('address'),
'number' => $request->input('number'),
]);
return redirect()->route('dealer')->withSuccess('done');
}
https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller
Look at the example from the documentation. There exists no such route in your ressource controller.
Depending on what you want you either have to use dealer.index, dealer.show or dealer.edit
Normally you would also use the plural form and not the singular form of the word.
I'm trying to test my login endpoint where a successful response would return the access_token among other things.
I'm using RefreshDatabase, so I changed the login method on the controller to retrieve the client_secret via a DB call. I tested with a dd() and I can confirm that the client_secret changes on each phpunit run in the terminal. The credentials are correct and the API endpoint works - just not when it's run via a test. For example, I have the passport tables set up on my mysql server and I can login successfully when running Postman. It's only when trying to run a test do I get a 401 error.
Here is my AuthTest
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class AuthTest extends TestCase
{
use RefreshDatabase;
/**
* #test
*/
public function a_user_receives_an_access_token()
{
\Artisan::call('passport:install');
$user = factory('App\User')->create();
$response = $this->json('POST', '/api/login', [
'username' => $user->email,
'password' => 'password'
]);
$response
->assertJson([
'access_token' => true
]);
}
}
routes/api.php
Route::post('login', 'AuthController#login');
AuthController#login:
public function login(Request $request) {
$http = new \GuzzleHttp\Client;
try {
$response = $http->post(config('services.passport.login_endpoint'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => '2', //config('services.passport.client_id')
'client_secret' => DB::table('oauth_clients')->where('id', 2)->pluck('secret')[0], //config('services.passport.client_secret'),
'username' => $request->username,
'password' => $request->password
]
]);
return $response->getBody();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($e->getCode() == 400 || $e->getCode() == 401) {
return response()
->json([
'status' => $e->getCode(),
'message' => 'Your email and/or password are incorrect',
'expanded' => $e->getMessage()
]);
}
return response()
->json([
'status' => $e->getCode(),
'message' => $e->getMessage()
]);
}
}
I took a look at this question and the accepted answer: How to test authentication via API with Laravel Passport?
I am unable to use the following
public function setUp() {
parent::setUp();
\Artisan::call('migrate',['-vvv' => true]);
\Artisan::call('passport:install',['-vvv' => true]);
\Artisan::call('db:seed',['-vvv' => true]);
}
This results in an error:
PHP Fatal error: Declaration of Tests\Feature\AuthTest::setUp() must be compatible with Illuminate\Foundation\Testing\TestCase::setUp()
Edit: I just added
public function setUp() :void {
parent::setUp();
\Artisan::call('migrate',['-vvv' => true]);
\Artisan::call('passport:install',['-vvv' => true]);
\Artisan::call('db:seed',['-vvv' => true]);
}
but the problem still persists
Edit again:
If I test the oauth route directly, it passes.
public function testOauthLogin() {
$oauth_client_id = 2;
$oauth_client = OAuthClient::findOrFail($oauth_client_id);
$user = factory('App\User')->create();
$body = [
'username' => $user->email,
'password' => 'password',
'client_id' => $oauth_client_id,
'client_secret' => $oauth_client->secret,
'grant_type' => 'password',
'scope' => '*'
];
$this->json('POST','/oauth/token',$body,['Accept' => 'application/json'])
->assertStatus(200)
->assertJsonStructure(['token_type','expires_in','access_token','refresh_token']);
}
But my custom endpoint that uses guzzle fails. I do not know why
Edit again:
I think the issue is with Guzzle, but I'm not sure. I found another implementation of what I'm trying to do, which is the following:
public function login(Request $request) {
$request->request->add([
'username' => $request->username,
'password' => $request->password,
'grant_type' => 'password',
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
'scope' => '*'
]);
$response = Route::dispatch(Request::create(
'oauth/token',
'POST'
));
}
The above works.
I'm using oauth2 and my table users is "coUsers" . I added this in my User Model
App\User
protected $table = 'coUsers';
public function getAuthPassword()
{
return $this->pass;
}
AuthController
public function login(Request $request)
{
$request->validate([
'usuario' => 'required|string|email',
'clave' => 'required|string',
//'remember_me' => 'boolean'
]);
$credentials = [
'usuario' => $request->get('usuario'),
'password' => $request->get('clave'),
];
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()
]);
}
public function firstLogin(Request $request)
{
$request->validate([
'usuario' => 'required|string|email|unique:users',
'clave' => 'required|string',
'nuevaClave' => 'required|string'
]);
$user = User::where('usuario', $request['usuario'])
->where('clave', $request['clave'])
->first();
$user->clave = bcrypt($request['nuevaClave']);
$user->first_login = false;
$user->save();
return response()->json([
$user->toArray()
]);
}
Auth login works OK, but I want to use User::where in firstLogin.... I get this error:
Illuminate\Database\QueryException: SQLSTATE[42703]: Undefined column: 7 ERROR: column "usuario" does not exist
LINE 1: select count() as aggregate from "users" where "usuario" = ...
^ (SQL: select count() as aggregate from "users" where "usuario" = xxxxx#gmail.com) in file \vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 669
Look in the users table instead of using the table that I indicated in the model.
You may change 'usuario' => 'required|string|email|unique:users', to 'usuario' => 'required|string|email|unique:coUsers', in your firstLogin method
You may also change this 'unique:users' in validator method inside your App\Http\Controllers\Auth\RegisterController
'email' => ['required', 'string', 'email', 'max:255', 'unique:users']
to
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:coUsers'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
I have been trying to get this api up and running and keep on experiencing this error when I test in Postman.
1. api.php
Route::group(['middleware' => ['api','cors']], function () {
Route::post('auth/register', 'Auth\RegisterController#create');
});
2. RegisterController
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}}
Postman configuration set to Post, the body is set to raw and JSON(application/json) Below is the postman json code.
{
"name": "Walter White",
"email": "wwhite#someemaildomain.net",
"password": "testpassword"
}
Below is the error
Too few arguments to function App\Http\Controllers\Auth\RegisterController::create(), 0 passed and exactly 1 expected in file C:\xampp\examplestuff
In order to fix your registration you should change your route definition to:
Route::group(['middleware' => ['api','cors']], function () {
Route::post('auth/register', 'Auth\RegisterController#register');
});
I assume your RegisterController is using the trait RegistersUsers. This trait is providing the register method, which is using the RegisterController::create method to create the new user itself.
Pass Request to your create function like:
protected function create(Request $request){...
and access your data like this:
$request->name
you have to do validation also plz check below answer
protected function create(Request $request)
{
$data = $request->json()->all();
$validator = Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
if ($validator->fails()) {
foreach ($validator->messages()->getMessages() as $field_name => $message){
$messages[] = $message[0];
}
$messages = $messages;
$message = implode(',',$messages);
$response = $messages;
return $response;
}else{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}