Giter VIP home page Giter VIP logo

larapi's Introduction

Larapi

Larapi is an API-friendly fork of Laravel, batteries included. If you want to read a more in-depth description of the offerings and how to do modern API development in Laravel I have written a series of blogposts on the topic.

A Modern REST API in Laravel 5

Larapi comes included with...

  • Laravel 5.4
  • Laravel Passport for OAuth Authentication, including a proxy for password and refresh-token grants
  • A new directory structure optimized for separating infrastructure and domain code. Groups your controllers, models, etc. by resource-type. Read more and view the source code here
  • Optimus\Heimdal: A modern exception handler for APIs with Sentry and Bugsnag integration out-of-the-box
  • Optimus\Bruno: A base controller class that gives sorting, filtering, eager loading and pagination for your endpoints
  • Optimus\Genie: A base repository class for requesting entities from your database. Includes integration with Bruno.
  • Optimus\Architect: A library for creating advanced structures of related entities
  • Optimus\ApiConsumer: A small class for making internal API requests

Motivation

We maintain a fairly large Laravel API at Traede. Our philosophy is to utilize the framework as much as possible. However, we also strongly feel that the amount of people that use Laravel for API development is not as large as it could be. We feel that Laravel as a framework tries to focus more on traditional web development (i.e. rendering HTML). We try to modify the framework just a little bit so it is more suited for API development. Larapi is the result of the changes we have made at Traede in order to make Laravel more enjoyable as an API framework.

Installation

First clone the repository

git clone https://github.com/esbenp/larapi my-api

Install dependencies

composer install

Copy the .env file an create an application key

cp .env.example .env && php artisan key:generate

Migrate the tables.

php artisan migrate

Larapi comes with Passport include as the default authenticatin method. You should now install it using this command.

php artisan passport:install

Copy-paste the generated secrets and IDs into your .env file like so.

PERSONAL_CLIENT_ID=1
PERSONAL_CLIENT_SECRET=mR7k7ITv4f7DJqkwtfEOythkUAsy4GJ622hPkxe6
PASSWORD_CLIENT_ID=2
PASSWORD_CLIENT_SECRET=FJWQRS3PQj6atM6fz5f6AtDboo59toGplcuUYrKL

If you want to save it elsewhere or change the naming be sure to modify the LoginProxy in infrastructure/Auth/LoginProxy.php

Test installation

You can quickly test if the authentication works by creating an user using the include command.

php artisan users:add Esben [email protected] 1234

Now serve your application and try to request a token using cURL

php artisan serve
curl -X POST http://localhost:8000/login -H 'Content-Type:application/json' -d '
{
    "email":"[email protected]",
    "password":"1234"
}'

This should return a token.

{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImM0MWZiOWFjZjkyZmRiY2RhYjE0ZmEwYTFlMzMwYjBjYTEwMmRiMTA1ZGI4MmZjYzllZGUwMjRiNzI2MjA2YjRhZDU4MGZhMjUxODU2Y2RkIn0.eyJhdWQiOiIyIiwianRpIjoiYzQxZmI5YWNmOTJmZGJjZGFiMTRmYTBhMWUzMzBiMGNhMTAyZGIxMDVkYjgyZmNjOWVkZTAyNGI3MjYyMDZiNGFkNTgwZmEyNTE4NTZjZGQiLCJpYXQiOjE0ODk5NTM3MDYsIm5iZiI6MTQ4OTk1MzcwNiwiZXhwIjoxNDg5OTU0MzA2LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.SmsEyCEXBiwSgl0yMcjvCxoZ2a_7D6GDJTxTs_J-6yzUeJkOofrSV7RRafO3VvUckrNqy5sGgglrwGH_HN7_lNPU6XcgaaNzbzf-g7vCSzCicJiYZVzxqJpZVwqQ4WIQrc0lYdk7suZ7hwQulOD_Z79JhBNh1KSAyo3ABWHiRjh9NR_-iAjvlCohh7nAETDeVqoMrR99m3fwQYOjdtvRBHJ8Ei-Kx3Gn1DyOXyh8eGa5-yDtj-ZVI9x66YMXlm8wk4IMA_Oh7KJISfdpoQs4fPyrGsFAxQMFp02qEW2fzKl2eesZeiIAyDGWE4StHsuY3E4jZL0P-pjv08j5W4CBP0P64gkNw_GdbxlPPA-qZUzJlc3EtjrzZ9WZq3JAKKCGy5I1jHECDOqaQ1z7axm6rmxRWmXmRGwwkne8QxfPlXsN0sm5q98mJckeqCLUuir1VPyFn5Z-B7D80-sc7Zm-7zi-awJtZUGMcHSo_yNHXjVGcbJwFk04xoIL2QzMXpOVPLaUdlBp_obCJhdzT5Bx0o5SDdK2LwgEwbMkksqmrTJ7ypoezsc3ihVQIrMelK2lNfkH_cDcVdD3ub8oFTthbA62U6atXaIADcsgTCgOtgQ2uXTIko_btjECgL35LZDd8UxiyQT3w-pDrELGDPx17DQCsIZDJ8mC1s6E0d7EPsA","expires_in":600}

Now try to request all users GET /users using the newly issued token.

curl http://localhost:8000/users -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImM0MWZiOWFjZjkyZmRiY2RhYjE0ZmEwYTFlMzMwYjBjYTEwMmRiMTA1ZGI4MmZjYzllZGUwMjRiNzI2MjA2YjRhZDU4MGZhMjUxODU2Y2RkIn0.eyJhdWQiOiIyIiwianRpIjoiYzQxZmI5YWNmOTJmZGJjZGFiMTRmYTBhMWUzMzBiMGNhMTAyZGIxMDVkYjgyZmNjOWVkZTAyNGI3MjYyMDZiNGFkNTgwZmEyNTE4NTZjZGQiLCJpYXQiOjE0ODk5NTM3MDYsIm5iZiI6MTQ4OTk1MzcwNiwiZXhwIjoxNDg5OTU0MzA2LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.SmsEyCEXBiwSgl0yMcjvCxoZ2a_7D6GDJTxTs_J-6yzUeJkOofrSV7RRafO3VvUckrNqy5sGgglrwGH_HN7_lNPU6XcgaaNzbzf-g7vCSzCicJiYZVzxqJpZVwqQ4WIQrc0lYdk7suZ7hwQulOD_Z79JhBNh1KSAyo3ABWHiRjh9NR_-iAjvlCohh7nAETDeVqoMrR99m3fwQYOjdtvRBHJ8Ei-Kx3Gn1DyOXyh8eGa5-yDtj-ZVI9x66YMXlm8wk4IMA_Oh7KJISfdpoQs4fPyrGsFAxQMFp02qEW2fzKl2eesZeiIAyDGWE4StHsuY3E4jZL0P-pjv08j5W4CBP0P64gkNw_GdbxlPPA-qZUzJlc3EtjrzZ9WZq3JAKKCGy5I1jHECDOqaQ1z7axm6rmxRWmXmRGwwkne8QxfPlXsN0sm5q98mJckeqCLUuir1VPyFn5Z-B7D80-sc7Zm-7zi-awJtZUGMcHSo_yNHXjVGcbJwFk04xoIL2QzMXpOVPLaUdlBp_obCJhdzT5Bx0o5SDdK2LwgEwbMkksqmrTJ7ypoezsc3ihVQIrMelK2lNfkH_cDcVdD3ub8oFTthbA62U6atXaIADcsgTCgOtgQ2uXTIko_btjECgL35LZDd8UxiyQT3w-pDrELGDPx17DQCsIZDJ8mC1s6E0d7EPsA'

This should return a response like so

{"users":[{"id":1,"name":"Esben","email":"[email protected]","created_at":"2017-03-19 19:59:15","updated_at":"2017-03-19 19:59:15"}]}

You can refresh a new token by requesting POST /login/refresh and logout using POST /logout

Contributing

Please see CONTRIBUTING for details.

License

The MIT License (MIT). Please see License File for more information.

larapi's People

Contributors

esbenp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

larapi's Issues

exception": "Infrastructure\\Auth\\Exceptions\\InvalidCredentialsException

Post: /login giving response

{
  "status": "error",
  "code": 0,
  "message": "",
  "exception": "Infrastructure\\Auth\\Exceptions\\InvalidCredentialsException in /mnt/hgfs/app/my-api/infrastructure/Auth/LoginProxy.php:85\nStack trace:\n#0 /mnt/hgfs/app/my-api/infrastructure/Auth/LoginProxy.php(48): Infrastructure\\Auth\\LoginProxy->proxy('password', Array)\n#1 /mnt/hgfs/app/my-api/infrastructure/Auth/Controllers/LoginController.php(24): Infrastructure\\Auth\\LoginProxy->attemptLogin('[email protected]', '1234')\n#2 [internal function]: Infrastructure\\Auth\\Controllers\\LoginController->login(Object(Infrastructure\\Auth\\Requests\\LoginRequest))\n#3 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(55): call_user_func_array(Array, Array)\n#4 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\\Routing\\Controller->callAction('login', Array)\n#5 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(203): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Infrastructure\\Auth\\Controllers\\LoginController), 'login')\n#6 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Route.php(160): Illuminate\\Routing\\Route->runController()\n#7 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(572): Illuminate\\Routing\\Route->run()\n#8 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#9 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#10 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(574): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))\n#11 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(533): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))\n#12 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(511): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))\n#13 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))\n#14 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))\n#15 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(30): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#16 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))\n#17 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))\n#18 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#19 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))\n#20 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))\n#21 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#22 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))\n#23 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))\n#24 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#25 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))\n#26 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))\n#27 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#28 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))\n#29 /mnt/hgfs/app/my-api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))\n#30 /mnt/hgfs/app/my-api/public/index.php(53): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))\n#31 {main}",
  "line": 85,
  "file": "/mnt/hgfs/app/my-api/infrastructure/Auth/LoginProxy.php"
}

Just some questions

Hello,

i discovered your blog and i love this structure more easier but i have some questions with relationship.

PUT /users/1 => update user information
{
	'user': {
		'metas': [
			{
				'name: 'Name 1',
				'value': 'Value 1'
			},
			{
				'name: 'Name 2',
				'value': 'Value 2'
			}
		]
	}
}
  1. How work relationship ?
    I can't understand where to put method for checking if parameter is in request and create/update data in request.

  2. How to load relationship ?
    In older work i have in my model protected $with = ['author']; but this code doesn't work.

Thank you.

can't get acess token in LoginProxy

Hello,

it's not Larapi issue I used some part of your configuration to mount my backend API for SPA React UI, I focused on authentication (login logout) part, everything works fine for authentication (I get the token and user can refresh to get new one).

but when i try de Logout i get FatalThrowableError when trying to get user access token in LoginProxy

Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function token() on null in file LoginProxy

I did not make any changes to LoginProxy, maybe I missed something from my project setup, can you give me a track of the possible cause of this issue.

Login not possible

Hello,
I am trying to use the larapi repository on a homestead server.
The login neither works via vue-resource nor Postman nor curl.
I'm sure that email & password are correct, but I always get the same response.

This is what i get in the console:
POST https://dev.moodular.co/auth/login 401 () - vue-resource.es2015.js?fc90:1073

The exception prints out this:

{"status":"error",
"code":0,
"message":"",
"exception":"Infrastructure\\Auth\\Exceptions\\InvalidCredentialsException in
\/home\/vagrant\/dev\/myapp\/infrastructure\/Auth\/LoginProxy.php:85\nStack trace:\n#0
\/home\/vagrant\/dev\/myapp\/infrastructure\/Auth\/LoginProxy.php(48):
Infrastructure\\Auth\\LoginProxy->proxy('password', Array)\n#1
\/home\/vagrant\/dev\/myapp\/infrastructure\/Auth\/Controllers\/LoginController.php(24):
Infrastructure\\Auth\\LoginProxy->attemptLogin('[email protected]', '1234')\n#2 [internal function]:
Infrastructure\\Auth\\Controllers\\LoginController->login(Object(Infrastructure\\Auth\\Requests\\LoginRequest))\n#3
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Controller.php(55):
call_user_func_array(Array, Array)\n#4
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ControllerDispatcher.php(44):
Illuminate\\Routing\\Controller->callAction('login', Array)\n#5
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php(203):
Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route),
Object(Infrastructure\\Auth\\Controllers\\LoginController), 'login')\n#6
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php(160):
Illuminate\\Routing\\Route->runController()\n#7
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php(559):
Illuminate\\Routing\\Route->run()\n#8
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php(30):
Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#9
\/home\/vagrant\/dev\/myapp\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php(102):
Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))\n#10
... }

I hope someone can help on this issue.
Have a nice day!

How to create listeners?

I badly need an example of Event/Listener in larapi.
I tried dozens of ways by my listener is never run.

Thank you.

CORs issuse

Hi,

I built up this APi but when i tried to connect via a React App (with browser) im having some troubles:

XMLHttpRequest cannot load http://localhost:8000/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

It looks that there is a COR problem, but i have no idea how can i fix it up using your app.

Where should i change headers in order to add Access-Control-Allow-Origin?

Thanks!!

Namespace error in windows

Hi! First of all, I want to thank you for your great tutorial about REST API development and for providing this fork.

I don't know if this is a bug or not but when developing in Windows I encounter an error regarding routes, the error says Class Api\:\path\larapi\api\Users\Controllers\UserController does not exist.

In this line of codes https://github.com/esbenp/larapi/blob/master/config/optimus.components.php#L5-L6, I manage to fix the error by removing base_path()

so it should look like this
'namespaces' => [ 'Api' => DIRECTORY_SEPARATOR . 'api', 'Infrastructure' => DIRECTORY_SEPARATOR . 'infrastructure' ],

InvalidCredentialsException

after clone and install with composer and create new user i get this error when i try to login with created users

File:

/Applications/XAMPP/xamppfiles/htdocs/my-api/infrastructure/Auth/LoginProxy.php

Stack trace:

Infrastructure\Auth\Exceptions\InvalidCredentialsException in /Applications/XAMPP/xamppfiles/htdocs/my-api/infrastructure/Auth/LoginProxy.php:85
Stack trace:
#0 /Applications/XAMPP/xamppfiles/htdocs/my-api/infrastructure/Auth/LoginProxy.php(48): Infrastructure\Auth\LoginProxy->proxy('password', Array)
#1 /Applications/XAMPP/xamppfiles/htdocs/my-api/infrastructure/Auth/Controllers/LoginController.php(24): Infrastructure\Auth\LoginProxy->attemptLogin('[email protected]', '1234')
#2 [internal function]: Infrastructure\Auth\Controllers\LoginController->login(Object(Infrastructure\Auth\Requests\LoginRequest))
#3 /Applications/XAMPP/xamppfiles/htdocs/my-api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(55): call_user_func_array(Array, Array)
#4 /Applications/XAMPP/xamppfiles/htdocs/my-api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\Routing\Controller->callAction('login', Array)

@pmccarren could you help me? Thanks in advance

use Laravel\Scout\Searchable throws error.

When adding the Searchable trait to a Illuminate\Database\Eloquent\Model, PHP throws error:

[Symfony\Component\Debug\Exception\FatalThrowableError]
Class 'AlgoliaSearch\Version' not found

Wrong auth

Option 1: Login success -> ok not problem
Option 2: Login unsuccess -> "exception 'Infrastructure\Auth\Exceptions\InvalidCredentialsException' ... "

Can help me, plz ?

commands artisan

Hi, the commands artisan not working, need update bootsrap/app.php for overrides path your application

app.php

// $app = new Illuminate\Foundation\Application(
//     realpath(__DIR__.'/../')
// );

$app = new Infrastructure\Application(
    realpath(__DIR__.'/../')
);

Application

<?php  

namespace Infrastructure;

class Application extends \Illuminate\Foundation\Application
{
    /**
     * Overrides the path to the application "app" directory.
     *
     * @return string
     */
    public function path($path = '')
    {
        return $this->basePath.DIRECTORY_SEPARATOR.'api';
    }
}

Question: How a SPA should be handling token refresh

I just read the lastest blog post (awesome tutorial btw) and as far as I understand, it needs an extra request to refresh the token, this leave me questions regarding the implementation on a SPA:

Is the SPA job to track the token expiracy in order to request a refreshed one before any other resource request takes place?

Refreshing the token within the same resource request would not be better?

proposal: artisan command to bootstrap new resources

As I started to use larapi, I found my self using something like cp && find|sed to bootstrap a new resource from a "template" directory. I have been considering adding that functionality into larapi itself in the form of an artisan command (e.g. ./artsian larapi:resource:add).

This utility would copy a "template" directory to /api and perform the necessary find/replace to setup the filenames and variables. Additionally there could be extra setup steps (add SP in app/config.php for example).

I'd like to gather feedback and see if this would benefit others? Would this help new users of larapi?

I welcome all questions/comments/feedback!

Cannot refresh *access_token*

I have defined a route

Route::get('/refresh', 'AuthController@refresh');

to refresh the access_token, But I get a 401 response back from the route.

How do I refresh the access_token?

How to consume with JS App?

Hey, having trouble consuming this with a JS app. Let's assume the endpoints are at api.domain.com but the client is loaded from domain.com. The CORS bit isn't really an issue but I can't use the refresh token because it's in an HTTP ONLY cookie. So, how would one go about consuming this API from a js client on a different domain?

How do I create a user using laravel passport?

I clone the larapi repo and installed the dependencies successfully then I made following request using curl:

curl -X POST -H 'Content-Type: application/json' -d '{"user": {"email": "[email protected]", "name": "A user", "password": "12345678"}}' http://apis.mydomain.dev/users

server returns following response:

{
   "status":"error",
   "code":0,
   "message":"Unauthenticated.",
   "exception":"Illuminate\\Auth\\AuthenticationException: Unauthenticated. ......."
   "line":66,
   "file":"project/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php"
}

Login with email only

Larapi is a good framework which I'm using it and it works totally fine.
Now i'm facing a challenge, i.e. somehow I need to enable a user to login with only email.
Anyone have idea how to do this? Anything like loginUsingId and it with generate access_token and refresh_token?

InvalidCredentialsException when getting access token via POST

Steps to Reproduce

  1. Install & configure Larapi
  2. Send a postman request to get the access_token
php artisan serve
curl -X POST http://localhost:8000/login -H 'Content-Type:application/json' -d '
{
    "email":"[email protected]",
    "password":"1234"
}'

Expected Result:

  • The access_token should be returned as response

Actual Result:

  • Infrastructure\\Auth\\Exceptions\\InvalidCredentialsException is thrown in infrastructure/Auth/LoginProxy.php:85

Root Cause

  • $this->apiConsumer->post('/oauth/token', $data); throws an internal Server error in infrastructure/Auth/LoginProxy.php
  • Replicating claims as headers is deprecated and will removed from v4.0. Please manually set the header if you need it replicated.

Resolution

  • composer require lcobucci/jwt=3.3.3
  • laravel/passport uses thephpleague/oauth2-server which uses lcobucci/jwt "3.3.3".

Wrong install process description

I tried to follow the readme install description.

I tried php artisan passport:install
and got

root@debian:# php artisan passport:install
Encryption keys generated successfully.

                                                                                                                                               
  [Illuminate\Database\QueryException]                                                                                                         
  SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "oauth_clients" does not exist                                                          
  LINE 1: insert into "oauth_clients" ("user_id", "name", "secret", "r...                                                                      
                      ^ (SQL: insert into "oauth_clients" ("user_id", "name", "secret", "redirect", "personal_access_client", "password_clien  
  t", "revoked", "updated_at", "created_at") values (,  Personal Access Client, **********************, http://localhost, 1  
  , 0, 0, 2017-04-20 16:11:35, 2017-04-20 16:11:35) returning "id")                                                                            
                                                                                                                                               

                                                                                       
  [PDOException]                                                                       
  SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "oauth_clients" does not exist  
  LINE 1: insert into "oauth_clients" ("user_id", "name", "secret", "r...              
                      ^                                                                
                                                                                  

I did php artisan migrate and after that php artisan passport:install passed.

I think php artisan migrate should be moved upper in the readme file.

Get user in LoginProxy

Hi, I'm interested on get the user to return to angular2 in LoginProxy@proxy, but I did not find which class or object returns this.

I need something like this:

[...]
public function proxy($grantType, array $data = [])
    {
        $data = array_merge($data, [
            'client_id'     => env('PASSWORD_CLIENT_ID'),
            'client_secret' => env('PASSWORD_CLIENT_SECRET'),
            'grant_type'    => $grantType
        ]);

        $response = $this->apiConsumer->post('/oauth/token', $data);
        // dd($response, $data, self::REFRESH_TOKEN);
        if (!$response->isSuccessful()) {
            throw new InvalidCredentialsException();
        }

        $data = json_decode($response->getContent());

        // Create a refresh token cookie
        $this->cookie->queue(
            self::REFRESH_TOKEN,
            $data->refresh_token,
            864000, // 10 days
            null,
            null,
            false,
            true // HttpOnly
        );
      
      
        return [
            'user' => /* User with this token or refresh token */,
            'access_token' => $data->access_token,
            'expires_in' => $data->expires_in
        ];
    }

[...]

I thought something like $this->auth->user() but it seems it's not defined.

What am I doing wrong?

Thanks!

Problems using array parameters on Route::group()

Hey there,

I'm having problems using parameters like 'middleware' on Route::group() facade static method,

And using param 'middleware' like this:

Route::group(['middleware' => 'role:admin'], function () {
        Route::post('create','AppointmentController@create');
});

The error message is:
Symfony\Component\Debug\Exception\FatalErrorException: Illuminate\Routing\Router::loadRoutes(): Failed opening required 'Array' (include_path='.:/usr/share/php')

I'm aware that we can circumvent this problems by using middleware() on each post/get/method, but i was looking for a solution to avoid code duplication.

Hard to integrate to existing projects

Nice work you doing. The only problem i have with this api template is that it doesnt use laravel's standard folders and structure thus making it really hard to integrate. Laravel users are already accustomed to the laravel project folder and file locations. This app requires a lot of fiddling and restructuring of the default laravel project to greater finer details, which to me, i dont think is necessary.

Want to login user without password(for google and facebook verfied user.)

Hello,

First of all, thank you for building such an awesome API project. I am developing login with facebook and google module where I want to login without a password. can you please tell me how to do this in the plugin because I am not finding anyway. I tried to change login proxy class in infrastructure folder but nothing worked. please help me.

how to use views in larapi

Hello, I have developed my whole api project in larapi and glad to tell you that i am very happy for using this. I am stuck in a problem where i want to send mail from api which will take the html data from views folder. i dont know how to do this in the larapi structure. please help me out. Thanks in advance.

Update composer

Hi, your api library it's very good, please, for work login update composer.json upgrade library passport to 3.0

"laravel/passport": "^2.0",
to
"laravel/passport": "^3.0",

Too many connections error sql

I then increase to max for max_connection, but error again.
I don't change config queue and database on project
Please help me.

How can I manage more than one client in the proxy?

The option to store the id and the secret of the client in the backend and only to receive the credentials of the user and then attach the credentials of the client to make the request of the tokens seems interesting to me and I have read that they recommend doing this in several publications. However, I have two doubts about this.

  1. How could I manage more than one client in my proxy?

  2. How could you identify the requests among different clients?

Many questions on Part 4 and OAuth

First I have to say that your series is one of the best out there, especially Part 4 about Laravel Passport and Authentication. But I feel a bit like after a Lost episode, I had a billion questions, and now I have a billion more ;)

So let's dive in:

1/ What are the security implications of leaking a client id and/or secret? I mean I get the idea of added security, it never hurts, but I have a difficult time understanding the real danger of the client secret being hacked. After all it is the Password Grant, not the Client Credentials one. Plus, according to the specs, Password Grant should be used only with first party clients (trusted). So is the added security of using a proxy worth the overhead?

2/ We should use a client id/secret per client (or application). But in your example the proxy is responsible for not only the client secret but for the client id as well. Shouldn't the client id be passed along the user/pass? Or should we use another code to identify the client for which the proxy will get the id/secret?

3/ If you cannot trust your javascript application to keep a secret, you shouldn't trust it to keep the refresh token. And if I get what you are doing, you only exchange cookies between the client and the proxy to handle the Refresh Grant. Alex Bilbie seems to go one step further in implementing that strategy for the access token as well (see https://github.com/thinkingmik/api-proxy-laravel or https://alexbilbie.com/2013/09/securely-store-access-tokens-in-single-page-web-app/). It uses the proxy and cookies for every api call. Do you think this is going one step too far? Does using a short lived access token mitigates for this?

4/ Is it good practice to set the refresh token to never expire (that's what you do by setting its expiration to now + 10 days as the token is sent back every time it is refreshed). Shouldn't we use an end of the week strategy for example, a fixed date?

5/ Do you think using this proxy strategy resolves the issue of managing a cross-domain SSO? If all we exchange are encrypted cookies and they are managed by a thin proxy layer, then this could potentially solve cross domain single sign on.

I'll stop here, I have many more, but outside the scope of your article. I may ask those to Alex Bilbie first, see what he has to say about it.

Again, thank you for reading, and thank you for your excellent four part series.

Inbound & outbound webhooks

Your articles are awesome.

Is there any due date for "inbound & outbound webhooks" article and corresponding package? I'm looking forward the next issue. Thanks.

what's the point on having a proxy ?

what's the point on having a proxy, one's the proxy url is exposed any one can use the link to create access tokens with same app id and secret since it's handled inside proxy..

Cannot start api

Hi @esbenp : I already follow all the instruction step by step, then when I try to run the app, it return error:
Class Infrastructure ....\infrastructure\Api\Controllers\DefaultApiController does not exist

is there any installation that I missed

Thank's in advance

For correct work under Windows

Remove base_path() from config i think not good idea.
I think, that good idea change file

Optimus/distributed-laravel/RouteServiceProvider.php

replace line 72
$component = substr($componentRoot, strrpos($componentRoot, '/') + 1);
to:
$component = substr($componentRoot, strrpos($componentRoot, DIRECTORY_SEPARATOR) + 1);

esbenp, please fix it in package -)

GraphQL

HI,

I am using your laravel implementation for my API and trying to see how i can implement GraphQL into it. Any advise ?

struggling a bit with the how/where to set it up considering your structure different to a default Laravel structure.

Thx

Filter function BUILDER expected Illuminate\Database\Query\Builder but Illuminate\Database\Eloquent\Builder given

I have this function in my User (Models)

public function drivers()
{
  return $this->belongsTo(Driver::class, 'id', 'user_id');
}
public function isDriverAvailable()
{
  return $this->drivers();
}

and then the UserRepository (Repositories)

use Illuminate\Database\Query\Builder;
class UserRepository extends Repository
{
  public function filterIsDriverAvailable(Builder $query, $method, $clauseOperator, $value, $in)
  {
      $query->whereIn('drivers.status', ['available']);
  }

It returned this error when I tried to filter using postman
"Type error: Argument 1 passed to Api\Users\Repositories\UserRepository::filterIsDriverAvailable() must be an instance of Illuminate\Database\Query\Builder, instance of Illuminate\Database\Eloquent\Builder given"

$this->belongsTo(Driver::class, 'id', 'user_id') <-- this one is Eloquent\Builder

but

filterIsDriverAvailable(Builder $query, $method, $clauseOperator, $value, $in) <-- expected arg Query\Builder

any ideas on how to resolve this?

POST /login route not exists in the route:list

I cannot submit a POST request on the LoginController which handles the LoginProxy because it does not exists in the route:list

This is the return of my php artisan route:list
| | GET|HEAD | oauth/personal-access-tokens | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser | web,auth | | | POST | oauth/personal-access-tokens | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store | web,auth | | | DELETE | oauth/personal-access-tokens/{token_id} | | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy | web,auth | | | GET|HEAD | oauth/scopes | | \Laravel\Passport\Http\Controllers\ScopeController@all | web,auth | | | POST | oauth/token | | \Laravel\Passport\Http\Controllers\AccessTokenController@issueToken | throttle | | | POST | oauth/token/refresh | | \Laravel\Passport\Http\Controllers\TransientTokenController@refresh | web,auth | | | GET|HEAD | oauth/tokens | | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser | web,auth | | | DELETE | oauth/tokens/{token_id} | | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy | web,auth |

controller not exist.

i was installed success but run get errors:

  • access: http://locahost:8000
    ==> {"status":"error","code":-1,"message":"Class Infrastructure\:....larapi-master\infrastructure\Api\Controllers\DefaultApiController does not exist"
  • access: http://locahost:8000/users
    ==> {"status":"error","code":-1,"message":"Class Api\:......\larapi-master\api\Users\Controllers\UserController does not exist"

DefaultApiController.php and UserController.php has exist on the my sourcecode.
thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.