Cookies or Session on Google Apps Script Webservice - session

I've created websites before where the server-side code has access to either Cookies on the browser or some sort of Session variables. I have not figured out how to do this with GAS. I can host a website with GAS, but I have no way of seeing the login session when a new page is loaded. How do I do this?
I would expect to see this information in the doGet() event, like this:
function doGet(e){
e.session.userid; //or something like this
}
NOTE: Anyone can access my site, even anonymous. So I can't rely on Google logins.

Google has a Session method.
https://developers.google.com/apps-script/reference/base/session
// Log the email address of the person running the script (visiting the page).
var email = Session.getActiveUser().getEmail();
Logger.log(email);
Edit:
In regard to the comment about cookie based identification.
I am no expert at this but my thought was to do something like this
Client JS
$(function(){
var clientCookie = document.cookie
google.script.run
.withSuccessHandler(function(cookieString){
if(cookieString){
document.cookie= cookieString
}
})
.craeteCookie(clientCookie) // server function to create cryptographic cookie string
})
Server Side
function createCookie(clientCookie){
if(clientCookie){
//check cookie is valid
}
else{
// create client cookie
}
}

Related

How to check if user is still logged in google?

I am using Google OAuth through Laravel Socialite to authenticate all the users in my web app.
I need the user session to end as soon as possible if user logs out of his google account.
I am trying to set up a middleware that would perform regular checks if user is still signed in with google. But I can't find a way to ask "Is user#example.com still the current user on google?"
I tried to get \Socialite::driver('google')->user() in the middleware but that doesn't seem to work without doing a redirect to google beforehand. I would like this check to be as quick and unobtrusive as possible. It should also work during a background ajax call.
It seems that it would be trivial using the client side authentication as there is gapi.auth2.init().isSignedIn.get(). However, that would mean I have to ask users for two authorizations (server side and client side) which seems wrong.
Looking at the docs at google, I see nothing that would let me check their authentication status apart from reauthenticating. Access token won't expire on logout... Is there a workaround?
It turns out that we can actually use gapi javascript in tandem with Socialite - just use the same client token. I didn't suspect that I will just get all the info without logging in separately for browser session, but it works.
I added the following code to the end of my master blade template to check state for authorized users.
#auth
<script>
var currentUserEmail = '{{Auth::user()->email}}'; // user "sameness" criterion
var googleClientId = '{{env('GOOGLE_ID')}}'; // the same oauth client id
</script>
<script src="https://apis.google.com/js/platform.js"></script>
<script src="{{mix('js/checkGoogleAuth.js')}}"></script>
#endauth
The script checkGoogleAuth is a simple then, I copied the google tutorial and shortened it:
var auth2; // The Sign-In object.
var googleUser; // The current user.
/**
* Initializes Signin v2 and sets up listeners.
*/
var initSigninV2 = function() {
auth2 = gapi.auth2.init({
client_id: googleClientId,
scope: 'profile'
});
// Listen for sign-in state changes.
auth2.isSignedIn.listen(checkState);
auth2.currentUser.listen(checkState);
};
var checkState = function (user) {
//if signed out or changed user
if (!auth2.isSignedIn.get() || currentUserEmail != auth2.currentUser.get().getBasicProfile().getEmail())
$('.logout-username').click(); //click logout button
};
gapi.load('auth2', initSigninV2); //launch it
I hope it helps someone else as well!

Is it asp.net Core Cookie Authentication without identity session stateless yes or no?

I have been looking a lot of tutorials and always they say that the asp.net Core cookie authentication the user stays authenticated on the server side in a Session object with a session Id. But in the CookieAuthenticationHandler.cs SignInAsync only save the sessionId when Options.SessionStore exists, if this is not the case I suppose that in each request is send all encrypted claims without the need to store all data in to Session object (like token authentication). So, Can someone clarify it to me please.
CookieAuthenticationHandler.cs source code;
var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.Scheme.Name);
if (Options.SessionStore != null)
{
if (_sessionKey != null)
{
await Options.SessionStore.RemoveAsync(_sessionKey);
}
_sessionKey = await Options.SessionStore.StoreAsync(ticket);
var principal = new ClaimsPrincipal(
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
Options.ClaimsIssuer));
ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
CookieAuthentication can work just fine without enabling Session.
All the claims are serialized into the cookie and deserialized into a ClaimsPrinicpal by the Authentication middleware on each request.
So if you mean stateless as in no session state needed, yes, the state is in the cookie, passed with each request.
No.
To prove this, create a new app. Register a new user. Delete your database and recreate it. When you return to your app you will be treated as though you are still authenticated.
If anything, the cookie is simply used as a cache that lives beyond the session. Like any cache, you must check if it’s stale, which means synchronizing state between client and server.
And, as Phil Karlton said, there are only two hard things in computer science: cache invalidation and naming things.
Achieving statelessness should be treated as a goal, but not a religious mandate.
By default, without Session installed, it is stateless.
A simple test to prove it:
return a cookie to your client via CookieAuthentication/SignIn
save the cookie value somewhere
then SignOut (the server returns a SetCookie to reset the value of the authentication cookie)
Send a request from the client reusing the value obtained in 1.
despite the SignOut phase you will still be authenticated! If by default you had a server side session mechanism in place, this cookie would have become invalid because the session would have been destroyed and the server wouldn't be able to match the cookie with the session.

Greasemonkey/Chrome Extension cross domain login or session

I wrote a set of APIs which will consider you authenticated if you logged on the website (and therefore you have your cookies set).
I then wrote a Greasemonkey and a Google Chrome plugin that does different calls to my api/* calls. However, Ajax doesnt send cookie header over cross domain (remember it is plugin that is enabled when you are on facebook).
What are the best strategies to authenticate my user and authorize his api calls?
GM_xmlhttpRequest
indeed does an AJAX-call and sends the cookie header.
You can therefore simply call a website that returns the authentification status based on visitors cookies, return a simple result and use it.
Example
GM_xmlhttpRequest({
method: "GET",
url: "http://yourwebsite/loggedin.php",
onload: function(resp) {
var conti=resp.responseText;
loggedin = parseInt(conti); //let the webpage return 1 or 0

node.js Express/socket.io hybrid application with facebook

I am using express/socket.io combination in my node.js app. So far it's working fine.
Now, I need to store facebook user id and email id (after user being authorized) into session scope. I see there are lot of options and a bit lost here.. in my app, most of the communications happen through socket.io.. ultimately what i want is to access user id and email id anytime in the client side...
var express = require("express"),
fs = require("fs"),
app = express.createServer(
form({ keepExtensions: true })
),
io = require("socket.io");
socket = io.listen(app);
After being authorized, I suggest using the accessToken which is already in the cookies and then sending it through the socket.io and fetching the email and the id using graph.facebook or your own DB. The problem with storing user ID and Email is that it could insecure, since session hijacking could happen.
Facebook has its own experts on security to make sure it wouldn't be hijacked. Use it!
This might help:
http://criso.github.com/fbgraph/
After being authorized you can store the data in your session via express
http://expressjs.com/guide.html#session-support
On a very basic level:
// Get data from facebok and store it on a var `userData`
// server
socket.on('getUserData', function (callback) {
callback(facebookUserData);
});
// client
socekt.emit('getUserData', function(userData) {
console.log(userData);
});

Ajax Authentication Response

I have a login form that I am considering if it should be 'ajax'ed or not.
The reason I am contemplating this is because if the response of the ajax call is fixed (like 0 for invalid and 1 for valid) I can redirect the ajax request through the javascript console and log into the system maliciously.
Is there a way to solve this security issue?
Is that why all login forms I've seen so far (including here on stackoverflow) are non-ajax?
You need to make sure that all content which should be displayed only to logged-in users should only be transferred after the login process. The server-side should check on every request whether the user is logged in or not. This could be done by traditional methods (like session ids in cookie or post/get).
So in short: don't transfer fixed values but transfer a normal session id which vary from user to user.
You perform your login with ajax.
Server side validates the login and starts a session.
Even if the client ignores the response from the ajax call, it's important that any ajax calls check if the session was properly created when login, and refuse to do what's asked if the session wasn't properly opened at login time.
In PHP (example):
Login:
<?php
header('Content-type: text/json');
session_start();
if ( check_password() ) {
// send ok response
}
else {
// send not ok response
}
// if that session variable exists, then we logged in successfully
$_SESSION['user'] = $user;
other ajax calls :
<?php
header('Content-type: text/json');
session_start();
if ( ! isset($_SESSION['user'] )) {
// send not ok response
// on the client, this will redirect to the login page
exit;
}
$user=$_SESSION['user'];
... rest of the code here
For every ajax call, when the response arrives, you should first check if the response is ok -- up to you to determine how you want this represented.
As an example, a response might look in JSON like
not logged : { "ok":"N","error":"not logged in"}
logged : { "ok":"Y","data":[{"name":"xxxx","age":19},{"name":"yyy","age":91}]}
or { "ok":"Y","data":"Some text"}
etc, etc...
If it's ok, you proceed to handle the response. If not, you can for example redirect to the login page.
Note that with PHP, every ajax call you make includes the session ID automatically (it's a cookie), so PHP knows which session is associated with a particular request.

Resources