Using Sahana Rest API to create a custom front-end

28 views
Skip to first unread message

abc

unread,
Mar 31, 2021, 6:03:25 PM3/31/21
to Sahana-Eden
I am new to web developing using Python frameworks.

I want to use Sahana Eden as a backend and build a custom front-end (Vue.js).

The idea is to use Sahana Rest API:

However, I have a problem with authentication. In my custom front-end, I am trying to reproduce the login procedure (POST request to 127.0.0.1/eden/ with basic auth) in orer to get the cookie. While it works in Postman, I have no success in my front-end (browser) due to CORS and other errors.

Is there any way to implement authentication using Sahana back-end and a custom front-end?

Thanks!

Dominic König

unread,
Apr 1, 2021, 2:00:31 AM4/1/21
to sahan...@googlegroups.com
Hi--

the problem you describe is typical for Android WebView, where your front-end
runs local on the device, whereas Sahana is remote. In this case, WebView
prevents you from storing the session cookie - which looks like CORS but is
actually a specific restriction of this environment (Android).

Is that what you are doing?

If yes, then there is no way around the problem - you cannot use session-based
authentication in WebView, but have to authenticate each and every XHR
separately. You can only emulate a session on the device.

If that is not what you are doing, then more information is needed to
understand your problem.

Dominic
> --
> You received this message because you are subscribed to the Google Groups
> "Sahana-Eden" group. To unsubscribe from this group and stop receiving
> emails from it, send an email to sahana-eden...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sahana-eden/857fc203-e013-4f1e-bcd3-0a1fd
> 5ba999an%40googlegroups.com.

signature.asc

Dominic König

unread,
Apr 1, 2021, 3:01:41 AM4/1/21
to sahan...@googlegroups.com
Remember, however, that the Android behavior is correct.

It is problematic, if not outright dangerous, for your Vue app to accept a
session cookie from an origin other than its own - especially if it has access
to device functions such as camera or similar.

Some environments, though, allow you to catch and explicitly accept the
session cookie - but while it is possible, you shouldn't really do that.

Your Vue app really isn't just a front-end for Sahana, but in fact a separate,
standalone application, and it should therefore behave like a state-less API
client to Sahana - or in other words: your Vue app should treat Sahana as an
external web service, not as its own back-end.

If you change your thinking to this end, you will quickly find it all very
logical again - forget the front-end/back-end perspective, and think of web
services instead.

The only thing you loose is session-based authentication - you must settle on
request-based authentication. But other than that, the REST API is fully
available to the Vue app like for any other web service client.

Dominic
> https://groups.google.com/d/msgid/sahana-eden/2767257.e9J7NaK4W3%40aldebara
> n.

signature.asc

Dominic König

unread,
Apr 1, 2021, 3:10:57 AM4/1/21
to sahan...@googlegroups.com
torsdag 1 april 2021 kl. 09:01:34 CEST skrev du:
> It is problematic, if not outright dangerous, for your Vue app to accept a
> session cookie from an origin other than its own - especially if it has
> access to device functions such as camera or similar.

...not to mention that it is dangerous for Sahana if a separate site can get
at its session cookies. It is possible, yes - but usually seen as an attack
route (XSRF) rather than a regular access mode.

So, in a way, it is actually good that your login-attempt fails - it shows
that you work in a properly secured environment.

Like I said: think "external web service" instead of "back-end", and it will
all play very nicely.

Dominic
signature.asc

K Dos

unread,
Apr 1, 2021, 3:30:49 AM4/1/21
to Sahana-Eden
Thank you Dominic, I really appreciate your quick responses!

The problem has nothing to do with Android, I only used a minimal Vue.js webpage in my browser.

I also tried the simplest possible setup: just a simple index.html page. I tried to fetch information from Sahana Rest API service using either Ajax or Axios but I keep getting CORS errors. I dont try to get the session cookie, I try a request for getting organisations.json, with request-based authentication, as you said.

I attach the code for jQuery Ajax / Axios requests and the errors I get in the Chrome console.

orgs_ajax.png
orgs_ajax_err.png
orgs_axios.png
orgs_axios_err.png

K Dos

unread,
Apr 1, 2021, 3:32:20 AM4/1/21
to Sahana-Eden
[I am the OP, I accidentally switched mail account]

Dominic König

unread,
Apr 1, 2021, 4:01:19 AM4/1/21
to sahan...@googlegroups.com
Aha,

different environment, but fundamentally the same problem.

You just cannot load a resource in a browser from a different origin than
where your script came from - except by a <script>-tag (JSONP), but that is
not actually supported by Sahana.

You have three options:

1) you load your Vue-app from Sahana
2) you customise your Sahana instance to allow this via a Access-Control-
Allow-Origin header (this is not implemented by default for obvious reasons)
3) you implement a server-side back-end to your Vue app that loads the data
via web services

The most logical approach is (1) - just make your Vue app the index.html of
your Sahana template. Then Sahana is indeed the back-end to your app.

If you really just want to implement a Vue-based front-end to Sahana, then I
would go for (1): create a template, add your view app as views/index.html and
implement a controllers.py to deliver this view for the default/index
controller. Relatively easy thing to do, and endlessly extensible.

What you do with the standalone HTML document is though to create a separate
app, and if that is what you intend to do, you must go for (2) or even (3).

Dominic
> --
> You received this message because you are subscribed to the Google Groups
> "Sahana-Eden" group. To unsubscribe from this group and stop receiving
> emails from it, send an email to sahana-eden...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sahana-eden/494b4866-ddd1-4d52-8c4f-4fd64
> 524d515n%40googlegroups.com.

signature.asc

K Dos

unread,
Apr 1, 2021, 4:10:38 AM4/1/21
to Sahana-Eden
Wow, thank you Dominic. I will consider all the alternatives you state.

Dominic König

unread,
Apr 1, 2021, 4:20:38 AM4/1/21
to sahan...@googlegroups.com
torsdag 1 april 2021 kl. 10:01:11 CEST skrev du:
> If you really just want to implement a Vue-based front-end to Sahana, then I
> would go for (1): create a template, add your view app as views/index.html
> and implement a controllers.py to deliver this view for the default/index
> controller. Relatively easy thing to do, and endlessly extensible.

This can be as easy as copying the skeleton-template, and replacing the views/
index.html with your Vue app (obviously, you could simpify controllers.py a
little in this case).

That way, the /default/index page of your Sahana would deliver the Vue app,
and then accessing Sahana from the Vue app is no longer cross-origin, but
Sahana would indeed be your app's back-end.

But you need to decide what you want to do: a standalone in-browser app that
accesses Sahana via web service API, or an actual front-end for Sahana. These
are two very different things, even though they are frequently used
synonymously.

The best solution for the former is a local framework that routes the XHR
requests to Sahana, e.g. Cordova (in this case, however, you cannot have
session-based authentication).

The best solution for the latter is what I described above.

Dominic
signature.asc

Dominic König

unread,
Apr 1, 2021, 5:23:17 AM4/1/21
to sahan...@googlegroups.com
Good :)

If you look at the (somewhat outdated) EdenMobile - this is a standalone in-
browser app accessing Sahana, written with AngularJS and Apache Cordova.

In this case, Cordova establishes a local web service proxy that allows the
AngularJS app to load remote (Sahana) resources - and because the remote
resource is delivered locally then, there is no CORS limitation as such.

However, the app can neither connect to a remote session (the cookies won't be
stored and no way around), nor can you execute any scripts loaded from the
remote site. All you can do is exchange data with Sahana, but at least you can
do that much.

At the time, I did consider implementing an AngularJS front-end for Sahana
that could be used transparently by both the web app (a thick client) and
standalone in a mobile app. But this proved a bit too ambitious, I would have
needed much more time and/or hands to get this done, and then there is no way
to replicate the Python-style RAD support in any ECMA-based framework simply
due to the complexity of the browser environment and ECMA itself.

And RAD is what we make this for ;)

Dominic
> https://groups.google.com/d/msgid/sahana-eden/bacd5f8f-ff3b-4a4c-b577-eefe8
> df372e9n%40googlegroups.com.

signature.asc
Reply all
Reply to author
Forward
0 new messages