What is the best way to use API and hide responses - laravel

I have a SPA website built over Laravel and Vue.
I am using axios to get the responses and all working fine.
The most of the data is vendor, categories and products and nothing sensitive in it however products has some data which I need to use in frontend however I don't want my competitors to get hold on to that data.
How to do I go about that? so I get the data but it's hidden as well?
So I thought may be I encrypt it and then decrypt it but not sure if that's the right approach
{
"Products": [
{
"ID": 9950,
"VID": 114,
"Name": "TBH Special Burger ",
"Category": 224,
"Description": "",
"Image": "",
"Price": "250",
"DisplayPrice": 0,
"DealPrice": 0,
"Percentage": "15",
"Cust_Percentage": "0.00",
"DateTime": "2018-10-08 19:03:40",
},
],
}
In above response only percentage related data is I am trying to secure.

You are looking for Laravel Passport.
Laravel makes API authentication a breeze using Laravel Passport, which provides a full OAuth2 server implementation for your Laravel application in a matter of minutes.
With Passport, only authenticated users can access your data via API.
Read the documentation in the link above and give it a try.
If non authenticated users access your api by typing the url in his browser, this is the response that he will get:
{
"message": "Unauthenticated"
}
Consuming Your API With JavaScript
Laravel provides a middleware that allow you to consume your api from your JS app. From the docs:
Typically, if you want to consume your API from your JavaScript application, you would need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is add the CreateFreshApiToken middleware to your web middleware group in your app/Http/Kernel.php file:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
Hope it helps.

You can use API Resources to specify witch fields you would like to show in response
take look to docs:
https://laravel.com/docs/5.8/eloquent-resources

Related

ACCESS_TOKEN_SCOPE_INSUFFICIENT when trying to access Google Classroom course announcements

My user account can use the Google Classroom web UI to see all the announcements for a given course. Trying to pull them programmatically using the Google Classroom API.
I've set up an app with Oauth consent screen covering (for test purposes) ALL the scopes listed under the Google Classroom API, and can run the consent flow with my user account to get an access token.
I can successfully GET course details by curl'ing https://classroom.googleapis.com/v1/courses/<my course ID> using the access token obtained from the oauth flow. However, when I GET https://classroom.googleapis.com/v1/courses/<my course ID>/announcements with the same token, I get the following:
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "google.classroom.v1.Work.ListAnnouncements",
"service": "classroom.googleapis.com"
}
}
]
}
}
Behaviour is same in using both client libraries as well as raw REST calls.
Am I missing an auth scope (I switched them all on), am I just not allowed to do this since I'm not the course owner, or am I doing something else wrong? Advice please!
You apear to be using the courses.get method
In order to access this method your application needs to be authorized with one of the following scopes.
You also appear to be using the courses.announcements.list method
This method requires that your application be authorized with one of the following scopes.
The error message "Request had insufficient authentication scopes." means exactly what it says. The access token you are using was not authorized with one of the scopes needed for the courses.announcements.list endpoint there for you can not use it.
You need to delete the access token you have now and request authorization of the user using the proper scope for this method. Always make sure to delete your old token. When changing scopes in code your app does not always request authorization again if you just change the scopes in the code. You need to force it to request authorization again.
All the scopes
you should not be requesting all of the scopes of the user only the scopes that you need. If you only need readonly access make sure not to request write.
I had forgotten that my code explicitly defines the scopes when configuring the client that then builds the oauth request URL:
config, err = google.ConfigFromJSON(b, classroom.ClassroomCoursesReadonlyScope)
Changed to
config, err = google.ConfigFromJSON(b, classroom.ClassroomCoursesReadonlyScope, **classroom.ClassroomAnnouncementsReadonlyScope**)
and it works fine.

Try this API for Logging API returns "PERMISSION_DENIED"

I am trying to test the Google Cloud Logging API on the "Try this API" feature that Google Cloud Platform has on their documentation, but I get this response back:
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
I know that my response body is correct because it works with OAuth 2.0 but fails when I use API Key.
Auth 2.0:
Working request using OAuth 2.0
API Key:
Non-Working request using API Key
Google docs says that they generate their own API Key for this "Try this API" feature. https://developers.google.com/explorer-help/
Since Google is using their own API Key, I do not understand why I am getting a response status of PERMISSION_DENIED.
Edit:
Here is a link to the Try this API feature in Google Cloud Platform if you would like to give it a try. https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write?apix_params=%7B%22resource%22%3A%7B%22entries%22%3A%5B%7B%22logName%22%3A%22projects%2F%5BPROJECT_ID%5D%2Flogs%2Frequests%22%2C%22resource%22%3A%7B%22type%22%3A%22http_load_balancer%22%2C%22labels%22%3A%7B%7D%7D%7D%5D%7D%7D
Here is the python request that I am using in my code to create an entry:
import requests
entry = {
"entries": [
{
"logName": "projects/[PROJECT_ID]/logs/requests",
"resource": {
"type": "http_load_balancer",
"labels": {}
}
}
]
}
requests.post('https://logging.googleapis.com/v2/entries:write?key=[YOUR_API_KEY]', data=json.dumps(entry))
The API key was created from my user that has "logs writer", "logs viewer", and "logging admin" permissions. This theoretically should be all the permissions I need to make the post request. However, it is still returning a "PERMISSION_DENIED" status.
Any help would be much appreciated. Thank you in advance.
It looks like you are making a request to write data which isn't publicly writable. API Keys have no concept of user, they are only identifying you are allowed to call an API. So it looks like your API key request is working to the extent it can, but the response is telling you: I don't know who you are so I can't let you do this.
OAuth 2.0 is the solution here, as it acts on behalf of your account (you have to give consent), allowing the API to verify you have permission to take this action.
Service accounts are another option, to act on behalf of your project instead of your user, but they aren't practical from a web UI.

Session store not set on request

I want to open the default authentication provided by Laravel to my REST API. For this I am creating POST http://localhost:8080/api/login:
// In api.php
Route::post('/login', 'Auth\LoginController#login');
However, sending a POST request to this address gives me a runtime error in /media/Data/workspaces/git/mahlzeit/api/vendor/laravel/framework/src/Illuminate/Http/Request.php:
RuntimeException
Session store not set on request.
The payload I am sending is
{"name": "test", "password": "123456", "email": "test#test.com"}
although I don't think that's important here.
So.. the standard login for laravel is working - I don't see what I'm missing here.

Getting API error with square-commerce-v1 URL scheme

I'm trying to initiate a Square Register payment from a web app. The web app will only run on iPads that are within my control.
The HTML I'm using to call it takes this form:
Open Square Register
Where the data parameter is, I believe, a properly URL-encoded form of this:
{
"amount_money": {
"amount": 500,
"currency_code": "USD"
},
"callback_url": "https://mycallbackurl.org",
"client_id": "{{my_app_id}",
"merchant_id": "{{my_merchant_id}}",
"supported_tender_types": [
"CREDIT_CARD",
"CASH"
]
}
The Square Register app is giving me this error:
API ErrorSorry, we could not process the incoming request. Please try again or contact support.
What am I doing wrong? Is this possible to do from a web app, as I'm trying to?
This error can occur if your application is not authorized to use the Square Commerce API. From the documentation:
The Commerce API is currently available only to approved partners. If you're interested in using the Commerce API to integrate your iOS app with Square Register, please contact partners#squareup.com.
In their API docs it says that supported tender types should be nested under options:
{
"options": {
"supported_tender_types": [
"CREDIT_CARD"
]
}
}

Laravel 4 + Sentry 2 as Web service

My question is how do I use laravel 4 with sentry 2 to authenticate users that is calling my API? What are the proper ways in doing this?
Example: a user in native iOS app calls my Laravel Web service (returns JSON response), how can laravel+sentry authenticate the user?
Thanks in advance and comment if you need more info.
Like mentioned by Antonio, if the client is able to persist cookies you should be set to go.
But,I will tell you my research on this topic. I looked for API Token Implementation with Laravel. One I could find was by Terry Appleby and his implementation is a composer package with name tappleby/laravel-auth-token. I implemented a much simpler version of the package using Sentry 2 at http://rjv.im/post/78940780589/api-token-authentication-with-laravel-and-sentry.
I called it a dirty one because I didn't consider much about security, expiration of tokens etc., but to answer your question, the above version does work and it is not secure unless you are in https environment.
To help you more I suggest github.com/kippt/api-documentation. It is the API Documentation for an app called kippt.com. I picked this one because it is really simple and could be a starting point if you are new to developing APIs. See how they support different kinds of authentication. To summarize on what Kippt supports: Browser Session (I am guessing iOS does support cookies), HTTP Basic Auth (Pass username and password every time in the header) and Token (Pass a token in header of every request). On Token implementation of Kippt, it just returns a token to the client after a successful authentication and one can save and use that token. That token never changes. In my blog post, I create a new token every time user logs in.
Hope I could help.
If the client is able to persist cookies, you just login with Sentry and it should work. Otherwise, after a common Sentry authentication, create and store an authentication token in your users table:
$table->string('api_token',96)->nullable();
Then use it in all other calls:
{
"token": "a358dafd256cb5b26a944eacc1c7428a97f6d1e079c3f1972696f1bea7fff099",
"user": {
"id": "3",
"email": "joe#doe.com",
"permissions": [],
"activated": true,
"activated_at": null,
"last_login": "2014-03-08 11:17:48",
"first_name": null,
"last_name": null,
"created_at": "2014-03-08 10:29:08",
"updated_at": "2014-03-08 11:17:48",
"api_token": "a358dafd256cb5b26a944eacc1c7428a97f6d1e079c3f1972696f1bea7fff099"
}
}
An article about this: http://rjv.im/post/78940780589/api-token-authentication-with-laravel-and-sentry

Resources