Reputation: 2322
I'm building a web app using AngularJS and a REST-API build with the Flask framework.
The app consists of two parts:
A part where users don't have to be logged in: They can register, login, check out the features...
A part where users have to be logged in.
To keep things simple I was thinking to separate these two parts in two angular apps and let Flask direct you to the right app according to you being logged in or not.
I was wondering if this is a good approach? I think with this I can keep the authentication pretty simple.
Upvotes: 5
Views: 6240
Reputation: 1665
I don't have a good answer if separating it into two AngularJS apps is a good idea. But I think its not necessary to split them into two since its really easy to keep them as one AngularJS application and will make it easier to avoid duplication. I've written a tutorial series on building web applications using Flask and AngularJS together. You might want to check it out - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/
Upvotes: 0
Reputation: 506
Hey using Flask and Angular together is really nice full-stack. And if you're clever about your code you won't get any overlap like these other answers suggested. In fact, you'll get an extremely fast stack with modern frontend/backend separation. Check this code out: https://github.com/mattupstate/overholt
The Overholt app is a great example of an elegant combination of Flask serving up the backend for a frontend to hook into. Flask handles the API, the web-assets pipeline, and user authentication. Backbone or Angularjs handles the frontend webapp that is the product your site is delivering once users are authenticated.
Upvotes: 1
Reputation: 889
(Disclosure: I'm one of the developers of UserApp)
If you don't want to roll your own user management, you could try out the third-party service UserApp, together with the AngularJS module.
Follow the getting started guide, or take the course on Codecademy. Here's some examples of how it works:
Login form with error handling:
<form ua-login ua-error="error-msg">
<input name="login" placeholder="Username"><br>
<input name="password" placeholder="Password" type="password"><br>
<button type="submit">Log in</button>
<p id="error-msg"></p>
</form>
Signup form with error handling:
<form ua-signup ua-error="error-msg">
<input name="first_name" placeholder="Your name"><br>
<input name="login" ua-is-email placeholder="Email"><br>
<input name="password" placeholder="Password" type="password"><br>
<button type="submit">Create account</button>
<p id="error-msg"></p>
</form>
ua-is-email
means that the username is the same as the email.
How to specify which routes that should be public, and which route that is the login form:
$routeProvider.when('/login', {templateUrl: 'partials/login.html', public: true, login: true});
$routeProvider.when('/signup', {templateUrl: 'partials/signup.html', public: true});
The .otherwise()
route should be set to where you want your users to be redirected after login. Example:
$routeProvider.otherwise({redirectTo: '/home'});
Log out link:
<a href="#" ua-logout>Log Out</a>
Access user properties:
User info is accessed using the user
service, e.g: user.current.email
Or in the template: <span>{{ user.email }}</span>
Hide elements that should only be visible when logged in:
<div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>
Show an element based on permissions:
<div ua-has-permission="admin">You are an admin</div>
And to authenticate to your back-end services, just use user.token()
to get the session token and send it with the AJAX request. At the back-end, use the UserApp API to check if the token is valid or not. We're also working on a Python library.
If you need any help, just let me know :)
Upvotes: 0
Reputation: 67479
I'm not sure two separate apps is a good idea.
It seems you would have a fair amount of duplication if you do it that way, because I don't think the two apps will be mutually exclusive. At least, I imagine the public options will also be available when a user is logged in, right? That means that a good chunk of the public application, client and server-side, will have to be part of the protected application. This sounds hard to maintain.
Also consider the user experience. A user will have to download an entire new application at login and logout time, at least the first time until it gets in the browser's cache. Depending on the size of your application that could be a few seconds of waiting.
The standard approach is to have one Angular app and one Flask app. The Angular app begins and shows all the available options, and depending on what the user does Angular sends Ajax requests to Flask.
If the user tries to do something that requires login, then Flask will respond with a code 401 error. Angular then can show a login dialog to get the login credentials and then submit the Ajax request again, now with credentials, maybe as HTTP Basic Authentication over secure HTTP. From then on Angular can attach the login credentials to all requests, so that the user can now use all the options.
If you don't want to send login info with every request, then you can have a get_auth_token
endpoint in your Flask app that takes the credentials and sends a token back to Angular. Then Angular can attach the token to all subsequent requests.
The logout option in Angular then just drops the credentials and/or token to become unauthorized again.
I explain some of these ideas with more detail in this answer. Even though the context in that question was Node.js the principles apply to Flask as well.
You can also check out my tutorials on the topic. I'm using Flask on the server and Knockout.js on the client, but the concepts should translate directly if you use Angular instead of Knockout. Here is the three of them:
Upvotes: 10
Reputation: 15058
Disclaimer: I've used Flask a lot, Angular a little (always using Flask at the back end).
This is an option, but I think you'll duplicate a lot of code (if the features are the same between your applications e.g. viewing a 'demo' page). The best bet is to run it at the Angular level in a single application.
I remember reading an interesting couple of ideas in the Google Group so maybe that could help you.
Of course if you're comfortable doing it in Flask and want to get your product out as soon as possible then perhaps code sharing between controllers is the best way. There are disadvantages to this situation though; Flask must direct the user to the correct application, but an non-logged-in user then wanting to access a part where they must be logged in, would cause an app/page reload (as they must now use the second app) which I feel defeats the purpose for the single page web apps Angular was designed for.
Upvotes: 0