Yammer javascript SDK logout issue - yammer

I can successfully login with yam.platform.login but when I call
yam.getLoginStatus(
function (response) {
if (response.authResponse) {
yam.platform.logout(function (response) {
if (response) {
alert("logout success");
}
})
}
}
);
the inner callback function is never reached. Do people know what is happening?
EDIT: another strange behavior that could be related to the problem: after the above logout function call, the login status is still "connected" and I checked in Chrome that all cookies from yammer.com are deleted. But when I manually ask Chrome to delete the cookies, login status would return "unconnected".

Response from yam.platform.logout seems "false" after successful logout so you might try "if(response == false)" or even without if statement..

I was also facing the same issue. It is hard to believe that the issue still exists in 2018! I dug a bit more and found that after the app is authorized by user, Yammer server sends a cookie which gets stored in the browser somewhere (not tied to the session) and yam.platform.logout is unable to delete this cookie (Ideally it should!)
But I found a good workaround which is working neatly for me.
Below is JS in my login page:
$("#yammer-login").click(function(){
console.log("clicked");
yam.getLoginStatus(
function(resp) {
yam.platform.login(function (response) { //prompt user to login and authorize your app, as necessary
if (response.authResponse) {
console.dir(response); //print user information to the console
alert("login success");
}
$.ajax({
type:"POST",
url:"/setSession",
data:JSON.stringify(response,null,'\t'),
contentType:"application/json;charset=UTF-8",
success: function(result){
alert("Result from setSession is: "+result);
window.location.replace("/login");
}});
});
}
);
});
Here #yammer-login is the id for login element
<h2 class="sign-in">
<center>
Sign-in With Yammer
<br><br>
<span id="yammer-login">Click</span>
</center>
</h2>
Here is my workflow:
The JS on login page sends a POST request to setSession and sets the session. The execution of window.location.replace("/login"); sends a GET request to my server for /login url. As the session is now set, my server then redirects this request to the dashboard. After I click on logout button on the dashboard. I clear all the session cookies and redirect it back to the login page. As the session is now un-set- I see the login page again! All works smooth!
So, the next time user clicks on #yammer-login DOM element - the session gets set and she gets redirected to dashboard (this time without authorizing the app)!
Hope this helps someone who faces this issue like me in the future!

Related

Laravel 5 refresh login page after session times out

I have seen many posts very similar question and they talk about redirecting to login page when of course you are logged in and a session times out.
My problem is the Login page itself which is using auth:guest middle-ware.
If I am on Login page... for 120mins and session times out and now I enter credentials and click submit button I get TokenMismatchException error.
I want to refresh login page when session has expired such that it has a new csrf token.
Thanks,
K
Add following to the app/Exception/Handler
use Illuminate\Session\TokenMismatchException;
and to render method
if ($e instanceof TokenMismatchException) {
if ( !$request->ajax() ) {
return redirect()->back()->withInput();
}
}

How to handle authentication in Angular JS application

I am implementing an auth system in my angular js app.
What I am planning it like below:
Get user info(name and pass from login form)
Check whether user exists or not
if exists server respond with a session cookie and frontend will redirect to a certain page.
then user will do some task which will generate API request
API request should have cookie information that was sent on step 3
server check whether the cookie was generated or not and if cookie was found then respond with the API request results. And in my service I am doing something like
MyApp.service('myAuth', function($http, $q) {
this.authHeader = null;
this.checkAuth = function(){
//do api call and if success sets this.authHeader = response
}
this.isAuthenticaed = function(){
this.authHeader ? return this.authHeder : return false;
}
After submitting the login form I will call checkAuth and get my session cookie back from my server, how I can add the cookie information while doing the next REST call and also when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false, in Angularjs when it will navigate to another page does it resets after setting it true from the first call? And is my approach 1-6 good or do you have any specific suggestions?
Btw I checked previous so entries but those are not what I want to know.
I am not sure about your backend, but this is how I would do it
Create a separate login page (dedicated url not angular sub view or
modal dialog).
If the user is not authenticated redirect to this login
page. This is done by server redirects. This page may or may not use
angular framework, as it just involves sending a user\password to
server.
Make a POST (not AJAX request) from the login page, and verify on server.
On the server set the auth cookie. (Different frameworks do it differently. ASP.Net sets form authentication cookie.)
Once the user is authenticated redirect user to the actual angular app and load all its components.
This saves any code require to manage authentication on client side in Angular. If the user lands on this page he is authenticated and has the cookie.
Also default browser behavior is to send all cookies associated with a domain with each request, so you don't have to worry if angular is sending some cookie or not.
I use the http-auth-interceptor. http://ngmodules.org/modules/http-auth-interceptor
In my backend (asp.net mvc) I build a simple Authentication Service and return an http error 401 if the user is not authenticated.
Then I handle the error with a login-view in the SPA site.
The ideas put forth by the previous answers will work, but I think they're overkill. You don't need anything this complex.
how I can add the cookie information while doing the next REST call
Turn on withCredentials by default inside $httpProvider like so:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
Then remove the wildcard (if you had one) from the CORS-related headers, and set allow-credentials, on the server side. In my case, using Python + Flask + Flask-Restful, it's super easy and looks like this:
import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(origin='http://localhost:8100', credentials=True)]
Now cookies will be set and returned automatically and transparently by the browser. See these threads for more info:
$http response Set-Cookie not accessible
Angularjs $http does not seem to understand "Set-Cookie" in the response
when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false
As suggested above, have the server return 401 if the auth session expires or is deleted, and use $httpInterceptor in Angular to catch this like so:
app.config(function($httpProvider) {
var interceptor =
function($q, $rootScope) {
return {
'response': function(response) {
return response;
},
'responseError': function(rejection) {
if (rejection.status==401) {
// Modify this part to suit your needs.
// In my case I broadcast a message which is
// picked up elsewhere to show the login screen.
if (!rejection.config.url.endsWith('/login'))
{
$rootScope.$broadcast('auth:loginRequired');
}
}
return $q.reject(rejection)
}
}
};
$httpProvider.interceptors.push(interceptor);
});
(Disclosure: I'm one of the developers of UserApp)
You could use the third-party service UserApp for this, together with the AngularJS module.
Check out 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>
User info is accessed using the user service: user.current.email
Or in the template: <span>{{ user.email }}</span>
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>
Hide elements that should only be visible when logged in:
<div ng-show="user.authorized">Welcome {{ user.first_name }}!</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.
If you need any help, just let me know :)

Parital view show login page with fullsite if session out after computer left idle for long time

I have created an asp.net mvc razor application, in which I load a partial view in a div, which can be accessed after login.
<% using (Ajax.BeginForm("Showproducts", "Home", new AjaxOptions {
UpdateTargetId = "resdiv", OnBegin = "fstart()", OnSuccess = "fend()"
}, new { id = "_myform" }))
{ %>
.....
<% } %>
When a user leaves their computer for a long time (which makes the session time out automatically) and then clicks the submit button, the resdiv is filled with the full site with the login panel. I want to show the full site with login panel NOT in the resdiv. Is there any way to avoid this behavior?
Is there any way to avoid this behavior?
Yes, there is a way. I would recommend you reading the following blog post in which Phil Haack illustrates a very nice technique allowing you to override the Forms Authentication Module for AJAX requests and be able to send a 401 status code instead of redirecting to the login page.
Then on the client side you could use a global AJAX handler where you could test the status code and if it is 401 redirect to the logon page.
For example once you have installed the AspNetHaack NuGet you could add the following global error handler to your view:
<script type="text/javascript">
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
if (jqXHR.status == 401) {
// not authenticated => redirect to login page:
window.location.href = '#FormsAuthentication.LoginUrl';
}
});
</script>

MVC3 Razor Engine execution/rendering order

I have a few links (login, logout, and register) in the _layout template, where the links are shown depending on whether the user is logged in. Like so:
if (User.Identity.IsAuthenticated)
{
<span class="username">#User.Identity.Name</span>
<span class="link">#Html.ActionLink("Logout", "Logout", "Account")</span>
}
else
{
<span class="link">#Html.ActionLink("Login", "Login", "Account")</span>
<span class="link">#Html.ActionLink("Register", "Register", "Account")</span>
}
Problem is that the logout link is still displayed the first time the user logs out of the system (I would expect that to be immediately replaced with the login, and register links) - that is until the page is refreshed, or the user moves to another page. Here is the logout action code:
public ActionResult Logout()
{
FormsAuthentication.SignOut();
Session.Abandon();
return View();
}
I have gone through this link - http://mvcdev.com/differences-between-asp-net-razor-and-web-forms-view-engines/ - which explains the execution order of the Razor engine, but in my case it seems to be executing differently. Ideally I would expect the FormsAuthentication.SignOut() to execute before the User.Identity.IsAuthenticated in the _layout.
What am I doing wrong? Thanks!
That's normal, you need to redirect after logging out:
public ActionResult Logout()
{
FormsAuthentication.SignOut();
Session.Abandon();
return RedirectToAction("Index");
}
The reason this happens is because when the client requested the Logout link he was still authenticated (he sent the authentication cookie along with the request). Then inside the controller action you are logging him out (FormsAuthentication.SignOut()) which does nothing more than mark the authentication cookie for removal on subsequent requests. Then you return a view, and inside this view of course the user is still authenticated as this view executes under the same request and the cookie is still present.

Django - Start Session by Ajax Request

I need to know how to start a session by Ajax in Django. I'm doing exactly as described bellow, but it is not working! The request is sent correctly, but don't start any session. If a request directly without ajax it works! What is going on?
'# urls
r'^logout/$', 'autenticacao.views.logout_view'
'# view of login
def login_view(request):
username = request.GET.get('username', '')
password = request.GET.get('password', '')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse(user.get_profile().sos_user.name)
return HttpResponse('user invalido')
'# ajax in a html page
$(function(){
$.get('http://localhost:8000/logout/?username=usuario?>&password=senha', function(data){
alert(data);
});
You're not calling the login_view. You're ajax request is going to the /logout/ url which is calling the autenticacao.views.logout_view.
Also, The ?> after username=usuario doesn't look right in the your get url.
My guess is you should be doing something like http://localhost:8000/login/?username=usuario&password=senha. (but I'd need to see your login url mapping to be sure).
Also, you should be POSTing the login information and using HTTPS for security reasons, but that's a different issue.

Resources