Write web services with existing Laravel Controllers - php

I have a project in Laravel 5.2 and now I have to make the APIs for that. I tried to hit the localhost/myproject/login via postman as a post request with the parameters but it returns me the HTML in return. I have used Laravel's auth scaffolding for the authorization.
I am unable to find postLogin function in my project.
I have separated the routes but how can I change the existing functions for the API?
Route::group(array('prefix' => 'api/v1'), function()
{
Route::post('login', 'AuthController#postLogin');
});

Here is the postLogin that returns the json rather than the html code.
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
//return redirect()->intended('dashboard');
return response()->json(['status' => 1]);
}
}
If you have any trouble, let me know.

Related

How to properly access a scope in laravel?

I'm currently using Laravel Passport, and I can verify that there is current token saved by using localhost:8000/api/check that returns json below:
{"id":"1c080ff73c6592b8e35630ae36f45f5042c04d9a9ed26a7fafc3793c606484b619ed8792be65a658","user_id":1,"client_id":5,"name":"Personal Access Tokens","scopes":["administrator"],...}
But when I tried to use middleware scope for admin using localhost:8000/api/admin it returns an error
Illuminate\Contracts\Container\BindingResolutionException: Target class [scope] does not exist. in file
Here is the routes/api.php
Route::group(['middleware' => 'auth:api'], function(){
Route::get('check', 'TeamController#check');
Route::group(['middleware' => 'scope:administrator'], function() {
Route::get('admin', 'TeamController#index');
});
});
Here's the corresponding functions on TeamController.php
public function check(Request $request) {
return auth()->user()->token();
}
public function index(Request $request) {
return auth()->user()->token();
}
Somebody knows what I went wrong?
You most likely did not register the scope middleware.
"Passport includes two middleware that may be used to verify that an incoming request is authenticated with a token that has been granted a given scope. To get started, add the following middleware to the $routeMiddleware property of your app/Http/Kernel.php file:"
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
Laravel 7.x Docs - Passport - Checking Scopes

auth laravel always return false

I often create a login with Laravel, and it runs smoothly, but I don't understand the actual process run by Laravel php artisan make:auth. and now I want to try creating this login process myself to understand the actual process
I'm trying to make the login process run by myself without Laravel make:auth. create a user table with a password that hashed. when logging in Auth::attempt is always false, why?
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
This function is in the documentation of Laravel Manually Authenticating Users
if i dd(Auth::attempt($credentials)); always return false, so it can't go to route /home:
and my register controller like this:
public function create()
{
$user = User::create([
'name' => Input::get('name'),
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password')),
]);
return redirect::back();
}
how to deal with this?
i think laravel use json callback and middlware and some handled session and cookie
better use basic auth
and check by step to all work currectly in front to end
and see data send to backend currectly

laravel - how to return response from first middleware while using multiple middleware

i'm using laravel 5.7 with php 7.1 i'm using multiple middleware. I want to return response from my first middleware without executing second middleware how can i achive that?
my route are following:
// Client groups
Route::group(['prefix' => 'clients/', 'middleware' => ['header', 'database']], function () {
Route::get('/cron', 'FacebookController#cron');
}
now i want to return below response from header middleware when sessionid is wrong
return \Response::json(['error' => ['error' => 'Your session id or key is wrong', "code" => 401]], 401);
it return response but also execute database middleware i want to stop execution when return response from header middleware. how can i do that?

Laravel 5.3 API

When user enter username and password on the the browser and successfully logged in.
I like to make some API requests after user have logged in.
Laravel 5.3 provide api.php in routes folder.
in api.php I have included:
Route::group(['middleware' => ['auth']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
When requesting domain.com/api/test on the browser, for some reason it is redirecting to /home?
API token is not needed.
If you are specifying routes in api.php, you will need to use the auth:api middleware. So using your example it would be:
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
Notes about Token auth and Laravel 5.3:
If you've setup laravel's default auth system, you will also need to add a column for api_token to the user table. If you are using DB seeders, you might want to add something like:
$table->char('api_token', 60)->nullable();
to your users table seeder. Alternatively just add the column manually and fill that column with a random 60-char key.
When making the request, you can add the api_token as a URL/Querystring parameter like so:
domain.com/api/test?api_token=[your 60 char key].
You can also send the key as a header (if using Postman or similar), i.e:
Header: Authorization, Value: Bearer [your 60 char key].
I order to get a useful error if the token is incorrect, and not just be redirected to login, also send the following header with all requests:
Header: Accept, Value: application/json. This allows the expectsJson() check in the unauthenticated() function inside App/Exceptions/Handler.php to work correctly.
I found it hard to find clear docs from Laravel about using token auth with 5.3, I think it's because there's a drive to make use of Passport, and it supports tokens in a different way. Here's the article that probably helped most getting it working: https://gistlog.co/JacobBennett/090369fbab0b31130b51
first install the passport as stated here laravel passport installation
while consuming your own api add below line in your config/app.php in middleware section
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
now change your route to
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
now in your config/auth.php change these lines
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
The reason you are being redirected back to home is because the auth middleware checks if a user session is stored in your browser, but since api middleware does not make use of sessions (see app\http\kernel.php), your request is considered unauthenticated
If you would like to perform simple APIs that utilize sessions, feel free to add them in your web routes, and make sure to secure them by grouping them inside an auth middleware.
The standard behaviour in Laravel 5.5 is to delegate handling of authentication exceptions to app/Handler::unauthenticated(), in your project's application code. You'll find the code in there that redirects to the login page, and you can override it or perform further tests and contextualization in there. In previous versions of Laravel, 5.3 among them I believe, this exception handling was executed way down within the Laravel library within the vendor folder.

Globally accessible user object in controllers and models

I'm building a Laravel API which authenticates users using an authentication token. For any routes that need authentication, I'm wrapping them in an auth filter:
Route::group(array('before' => 'auth'), function() {
Route::get('user/account', 'UserController#getAccountDetails');
});
My auth filter basically decrypts the passed in authentication token and checks if it's valid:
Route::filter('auth', function()
{
// Try catch because Crypt::decrypt throws an exception if it's not a valid string to decrypt
try {
$authToken = Crypt::decrypt(Request::header('Authorization'));
// If there's a user tied to this auth token, it's valid
$user = AuthToken::where('token', '=', $authToken)->first()->user()->first();
if (!$user) {
throw new \Exception();
}
// Make the user globally accessible in controllers
} catch (\Exception $e) {
return Response::json([
'data' => [
'error' => 'You must be logged in to access this resource.'
],
'success' => false,
'status' => 403
], 403);
}
});
Pretty simple stuff, but I'm stuck on the next part. I want to be able to easily retrieve the current user record in my controllers and models.
For example, if I used Laravel's Auth library I could get the current user by doing Auth::user() in my controllers. I'd like to have that kind of functionality but I'm not sure how to build it. Could I write a class that gets instantiated after authentication with a static method that returns a User model?
Not sure if that's an option for you, but maybe you would like to use oauth2 instead of writing "your own" token based authentication?
There is quite nice ouath2 server wrapper for laravel project: oauth2-server-laravel.
According to it's documentation you can (for example for password flow authentication) put this in it's config:
'password' => array(
'class' => 'League\OAuth2\Server\Grant\Password',
'access_token_ttl' => 604800,
'callback' => function($username, $password){
$credentials = array(
'email' => $username,
'password' => $password,
);
$valid = Auth::validate($credentials);
if (!$valid) {
return false;
}
return Auth::getProvider()->retrieveByCredentials($credentials)->id;
}
)
And than you can you can authenticate (via username and password in that case) sending post request like that:
POST https://www.example.com/oauth/access_token?
grant_type=password&
client_id=the_client_id&
client_secret=the_client_secret&
username=the_username&
password=the_password&
scope=scope1,scope2&
state=123456789
Request will return generated token, and then you can make api calls as usual, just putting the token in the post data.
In your api logic getting the user by token is quite simple in that case, just run:
User::find(ResourceServer::getOwnerId());
It will makes stuff like: refresh tokens, other grant flows, scope access, clients management a lot easier. Out of the box in fact.
You can also secure any particular route like that:
Route::get('secure-route', array('before' => 'oauth', function(){
return "oauth secured route";
}));
You can find more details in oauth2-server-laravel documentation: https://github.com/lucadegasperi/oauth2-server-laravel
And oauth2 documentation: http://oauth.net/documentation/
It is true that the Auth::user() method is quite convenient. So, why not simply extend the Auth class to write your own authentication driver ? You can find all needed doc here.
You can then just use the Auth facade just like in every other laravel app you could write… wonderful, isn't it ?

Categories