I'm building a site that has to display data collected from an external web service. This service provides multiple data endpoints that are all authenticated against via OAuth.
Rather than each view having to hit an internal method to generate this data (and login to the external service each time) it seems like it'd be much better to create a singleton that will (lazy) connect to the data provider service when a view needing the data is first loaded, and then the various methods supporting the views could just call this same service provider to get the data.
Would this be best in the Laravel world as a service provider? As a helper class with a singleton? Or some other way?
Your Laravel application boots from scratch every time it receives a request (you can cache objects from a previous request, but not an instantiated service), so it won't be possible to create a service that keeps running authenticated between requests (at least with PHP).
It's not uncommon to create a service and authenticate once per request.
That being said, you can create a service and bind it to the container using $app->bind() or $app->singleton().
Docs about it here: https://laravel.com/docs/5.5/container
Related
I am researching for develop an API consumed application using laravel, laravel passport , lumen and AngularJS
I have 3 domains as follows
auth.dev - Laravel 5.4 + Passport oAuth server ( as a auth server )
api.dev - Lumen ( as a API seaver )
app.dev - php + angularjs ( single page app )
I can not properly configure those 3 together. I have setup auth.dev and it will successfully generate Tokens and I can use them from app.dev.
But my requirement is use 3 separate instance for API, Auth and APP
I tried to configure it via Lumen ( to validate Access tokens with auth.dev) but it is not working.
Is this possible or is there any suggestions to achieve this ?
I have recently been working on an implementation that is identical to this. It took a little bit of effort to make it work efficiently, but it's working!
Basically, if you care about validating the tokens you're receiving (which you should), you will need a way to forward the token that Lumen receives from client applications onto your OAuth service and return some details of that authentication to your Lumen app.
If you know that your Lumen API service is always going to run on the same machine, you could use some sort of RPC to save going over HTTP unnecessarily - I used a command line interface via a custom Artisan command in the OAuth service and a custom script to run it from the Lumen side which I call RemoteArtisan.
The other method is via HTTP, basically making your OAuth service provide its own very basic API endpoint. Something like this in routes/api.php should do:
Route::middleware('client')->get('user', function (Request $request) {
$helper = new App\FirstPartyClientHelper;
return response()->json($helper->getTokenOwnerDetails($request->bearerToken()));
});
My FirstPartyClientHelper is a simple class that parses the token to get the ID out of it and use that to fetch the resources from the OAuth DB that I want to send back to Lumen. You might not need to do lots of queries or send lots of data here, it could just be a simple pass/fail. Depends on your needs.
One thing I would recommend figuring out and sending back to your Lumen app though is what scopes were assigned to the token. You'll probably want to use these along with the various scope middleware available in Passport.
The only option here at the moment is to duplicate those middleware classes (CheckScopes and CheckForAnyScope) into your Lumen app and load them manually. But this is pretty straightforward as they're basic.
You may need to modify them so that they can see the scopes that come back from your OAuth endpoint through your Authenticatable class (typically the User model).
Either of these solutions are going to add some overhead to each request, so it's worth thinking about caching the result of this for some time on the Lumen end.
If you do that though, make sure it's not cached for a long time because it could allow expired tokens to still be considered as valid.
Alternatively, store the expiry time of the token somewhere in your cache and validate that against the time of the request to make sure the token hasn't expired.
Hope this helps.
I am working in symfony. I am retrivind data from a web service.
Currently I am using "Listener" to get data using web service. Is it wring way to do through listeners?
Is there any concept of Models in symfony to get data using web service? rather than calling web service from listener!
Actually a listener isn't something that would fit your case. You need a regular service, because listeners are supposed to react to Symfony domain events.
On creating services, you should read the official documentation (though if you've created an EventListener then most parts of the manual would be familiar to you).
If you're wrapping a foreign API then you should definitely do some research on whether the API is already wrapped (packagist.org is a good start: here's a wrapper for Twitter's API for example). If it's not, then it's up to you to pick an HTTP client to communicate with the service, and wrap its API into a PHP class that you would then expose in your service.
To understand how exactly you want to do this, try searching Packagist for Symfony bundles that wrap some APIs. Here's a Foursquare API bundle that uses an abstracted client library for example. Note that it depends on Guzzle HTTP client, and also take a look at the Guzzle Client class.
Also, here's Google's official API client for PHP. You could grab some ideas from there, too.
I am writing a web service in PHP using the Slim framework. I have a web application and a mobile application which uses the web service. My web application posts some data to the web service and web service writes it to a database. But I also wanted the web service to send a notification to my mobile application.
I assume this is some kind of an event based action. How to perform this for PHP slim web services? Or in general, for a PHP web service?
I personally use the symfony2 EventDispatcher component to achieve what you speak of. It's a clean way to, well, implement an event-based architecture. This particular implementation of the mediator pattern can make your code extensible with minimal overhead (and much organization).
Link: http://symfony.com/doc/current/components/event_dispatcher/introduction.html
Note: The EventDispatcher can be used independently of symfony2. The above link contains the packagist link of the component.
Edit: If you are a fan of global variables, you could look into the do_action function in WordPress.
I think there is no easy way to implement a direct event notification from Slim to a mobile device. To do such thing you need to open a socket between device and server so you can send direct notification to the device.
With Slim, the easiest way to achieve what you want is to use the list/queue pattern and tell the device to periodically ping your web service (like every 30 sec) and check if there is something new in the queue.
I have a ZF1 project that was developed used the lean startup approach. I'm now ready to move into a more evolved project as I know what my users want, but I really want to develop using better techniques. I've decided to move from ZF1 to ZF2 for support reasons and this is where I'm at:
API(Client) - I have a "push only' API that users use to send me data
API(Admin) - The admins can consume the data pushed using a variety of metrics and aggregates
The API for clients is restful but just pushes into a Redis job queue currently and is processed via cron. This removes the need for clients to wait for their data to be inserted and their requests are returned immediately.
The API for admin is currently not restful and is actually consumed inside of the application only. I think that this is okay as I don't want to have a single page frontend or API consuming front end. I would rather data be returned immediately by the server.
This leaves me with the question of whether I have an API Service Module which provides all of the Models (Doctrine2 ODM POPOs), mappers, filters, and a service layer to access it all and then the controllers that need it can consume the API without making HTTP requests (via service calls).
Is this the proper way to structure or is there a more refined and acceptable approach? I like the service layer in general as testing will be more accurate and all clients / admins are using the same API (if it updates it is essentially updated immediately across the board as there are not separate projects).
I think the module you think of doesn't need to have an own built service layer which only forwards to another service (like Doctrine entitymanager or something else), it rather should only provide the other modules the required services by configuring the DI and encapsulate the required classes (like models, mappers, filters, ...).
In my company for this purpose there is always an 'Application' module (like it was in the early tutorials of ZF2). I dont know if this is still best practice, but there are some serious benefits regarding maintainance and structure.
You should consider defining a module dependency in the 'consuming' modules (like Client-API or Admin-UI).
It is also worth to take a look at the Doctrine library and DoctrineModule implementation, to get a feeling what a module should provide and where it makes sense to only provide a library.
I'm trying to create a simple User Provider in Symfony 2, but i have no idea how this is supposed to work with a webservice. Authentication in my company is handled by a RESTful webservice, with various routes:
POST /user, GET /user, POST /login
So, when creating a Symfony 2 app, my user provider must consult the web service in order to verify credentials and permissions. Is this possible? Is there a bundle for something like this?
Also, how can i achieve a good performance on this? The way the Symfony user provider works, i guess it will consult the web service on EACH request, in order to get the user data. Can this be avoided?
There are two great bundles you can use:
For dealing REST reqs try FOSRestBundle (https://github.com/FriendsOfSymfony/FOSRestBundle),
And for User Provider try FOSUserBundle (https://github.com/FriendsOfSymfony/FOSUserBundle)
Those are good bundles, and you can get good documentation, too.
You can do this by implementing an authentication provider and user provider, each will handle the call to your web service for auth.
You could have a client class to make the web service calls, and cache the response somewhere to avoid having it called every request, although the need for that depends on how slow the web service is.
I have done this approach so can fill in the gaps if you need.