How to handle API credentials in an Angular app? - javascript

I created an API in Laravel and I have a small SPA in Angular that logins in the app via an username & password and receive a token. With this token you can do some basic stuff with the API.
It's not ok to save the credentials (user&pass) in the Angular app (plain text - javascript etc etc). How can I handle this kind of auth in Javascript? What is a best practice?

After login, You can return the token and store in a localstorage for future use and refresh, and if you don't want put your token in every ajax call manually you can add to $http like:
$http.defaults.headers.common['Authorization'] = 'Bearer ' + storage.token;
I have tried this with angularjs and laravel with this library:
https://github.com/tymondesigns/jwt-auth

Related

Laravel : Get id from localstorage

I have an application using for backend Laravel and in frontend React.
In React, to retrieve the data of the logged user I use :
const user = JSON.parse(localStorage.getItem("userData"));
In laravel's web.php to get the logged user_id I use Auth::user()->id.
Since I'm using React for authentification and Laravel to serve the APIs, I can't use Auth::user()->id directly to read the logged user's id in JS.
I understand that I can't pass directly localstorage as it's something stored locally in the browser. I tried setting a token for the logged user using Laravel Passport and it's working. But how to retrieve the data of the logged user in web.php or a Controller ?
You can use Laravel Sanctum. Doc
In Laravel Sanctum your application use session & cookies instead of tokens for user authentication. So you can retrieve user data anywhere you want.

Hybrid Django Application - REST API Authentication

I am new to Django and have built a basic application (Django 3.1) which uses session authentication and a simple login page (username + password) to login a django user. It works fine. I would like to use javascript (vue.js) on pages accessible to the logged in user to call Django REST APIs, hosted on the same Django application.
Despite lots of googling, no one seems to give a clear authentication example of a hybrid Django app, augmented with APIs. I have used lots of APIs before so am familiar with the authentication options. My issue is how to get credentials to the javascript loaded by django templates in a secure manner.
IDEALLY I would like:
User logs in with username/password
django redirects to PAGE B, AUTOMAGICALLY SOMEHOW inserting user's token into a cookie/sessionStorage
A javascript function on PAGE B gets credentials from cookie/sessionStorage and calls API (using all the various options supported by django-rest-framework)
My Questions:
Question 1 ==> in my do_login view function (below), after successful authentication with Djangos inbuilt login method, do I need to create a cookie in HttpResponse (e.g. token=XXXXXXX), so javascript can access it? Is this secure?
def do_login(request):
....
login(request, user)
...
#create token here and return to user somehow in cookie/sessionStorage
return render(request, 'hello/logged_in_ok.html')
So my javascript can do something like this (demo code only):
function onButtonClick(){
let token = sesssionStorage.getItem("django_gave_me_this_token");
let response = callGetAPISomehow(token, "https://demo/rest/api/account/1")
.....
}
Question 2 ==> Most view methods finish up with:
return render(request, 'blah/blah.html', {'data': blah})
How do I set the cookie in the response this way? There is no response object to access.
All help appreciated

How to pass data from AngularJS frontend to Nodejs backend using PostgreSQL?

Ready login page and register page using HTML and AngularJS. I have connected database PostgreSQL, but I don't know how to pass data from AngularJS frontend to Nodejs backend using PostgreSQL.
You can do it by several ways like using
"$http" - https://docs.angularjs.org/api/ng/service/$http
or
"ngResource" - https://docs.angularjs.org/api/ngResource/service/$resource
Using these you can pass data to Node.js backend(I assume "Express.js"). Since DB data will be executed by backend you just need to post your login or registration values to back-end. Here is below is a simple $http process:
$http.post('/login', {
email: this.email,
password: this.password
})
.success(function(response){
// execute your response
});
Actually for login/registration and another security purpose I recommend using JSON Web Token (JWT). https://jwt.io/introduction/

Making server to server request to Google Calendar API

I am building a SPA using vue.js which has a PHP backend server (slim framework 3). These are two separate projects, leave on two different servers and the backend has no front end at all.
SPA (vue.js) makes requests to backend via ajax.
Now I want to implement Google Calendar API to create a calendar and events every time user creates a todo item. To do that I need server to server access to Google Calendar API (I might need to make changes to the event on GCAL even if user is not logged in).
What I am trying to understand, how can I get the access token (and refresh token) using Google JS library using vue.js and save this in the db so that my backend can use it to make offline requests to GCAL Api.
When I use the Oauth v.2 using the JS library, all I get is the access_token which cannot be using for server to server communications.
[UPDATE]
Ok, a little bit more information. I am following the guides from Google and my front end looks like this at the moment
jsbin
So I can successfully authorise user and access their calendar using the javascript sdk. But the token Javascript SDK returns is something like this
{
_aa: "1"
access_token: "xxxxxxx"
client_id: "yyyyyyyyyy"
cookie_policy: undefined
expires_at: "1456400189"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1456396589"
response_type: "token"
scope: "https://www.googleapis.com/auth/calendar"
state: ""
status: Object
google_logged_in: false
method: "AUTO"
signed_in: true
token_type: "Bearer"
}
I send this token to my backend server and try to make a request to GCAL api as follows
$token = $request->getParam('token');
$client = new Google_Client();
$client->setApplicationName('Web');
$client->setScopes([Google_Service_Calendar::CALENDAR]);
$client->setAuthConfigFile(ROOT_DIR . '/client_secret.json');
$client->setAccessType('offline');
$client->setAccessToken(json_encode($token));
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
And it returns error saying the token is expired. I checked the Google Code and found out the reason it returns this error is because of these lines
public function isAccessTokenExpired()
{
if (!$this->token || !isset($this->token['created'])) {
return true;
}
// If the token is set to expire in the next 30 seconds.
$expired = ($this->token['created']
+ ($this->token['expires_in'] - 30)) < time();
return $expired;
}
As you can see the token that comes from the front end doesn't have created field as well as no refresh_token field.
Thanks for updating the question! I am thinking the issue is that using the client-side flow does not allow you to get a refresh token. From the docs:
OAuth 2.0 client-side flow (AKA Implicit flow) is used to obtain
access tokens (it does not support the issuance of refresh tokens) and
is optimized for public clients known to operate a particular
redirection URI. These clients are typically implemented in a browser
using a scripting language such as JavaScript.
The authorization server MUST NOT issue a refresh token.
see for more: How to get refresh token while using Google API JS Client
You'd need to use the server-auth flow to get a token you can refresh and use long-term. Here's a quickstart guide for PHP.
One other thing to consider is that you will only receive a refresh_token the first time someone authorizes your app. After that, auth attempts will only return an access token. So if you lose the refresh token, you will need to either disable the authorization from your google account, or use the "force re-auth" option in the API.

Facebook Graph API: Client side requests without user login?

I'm trying to get graph api data for public Facebook events rendered in an html document. The site I need to put it on is made with a website builder so I don't have control over the server that generates the html. I can only insert JavaScript code into the page.
The only solution I've found now is by using an app access_token in the client side request:
FB.api(
"/<event_id>?fields=start_time,description",
function (response) {
if (response && !response.error) {
console.log(response.start_time, response.description);
}
},
{access_token: "<app access token>"}
);
I've read through the docs on access tokens
and the JavaScript sdk docs, but the app token solution I've found is not secure (from the docs):
... app access token should never be hard-coded into client-side code.
I don't think the user access token is the flow I want because I don't want people to have to log in; it's only for public events. I don't think the page access token is right either.
Is there:
a way to use the Graph API for public events without requiring a user to log in or without introducing an insecurity?
or a way to make sharing my app access token with the world have no bad consequences?

Categories