The user is not detected at login until the URL / login appears

I am using Play! A framework with a standard security module. What I see is when the user logs in, and the checks remember me, everything works fine. If they close the browser window, open it again and return to the page, the user will no longer be logged in, but if they go to the default login address / login, he will automatically register them and redirect them back to the main page with the correct user display at login into the system.

What's wrong is that the user has to click the login URL to find out that they are logged in? Am I missing something in my controller to do this?

Here is the controller in question, and my custom security class:

public class Main extends Controller {

    @Before
    public static void checkUser() {
        String user = Security.connected();
        boolean connected = Security.isConnected();
        renderArgs.put("isConnected", connected);
        if (!connected) return;
        User u = User.findUser(user);
        String displayName = u.firstName + " " + u.lastName;
        renderArgs.put("displayName", displayName);
    }

    public static void homePage() {

        List<Testimonial> testimonials = Testimonial.findAll();
        List<News> news = News.findAll();

        Twitter twitter = new TwitterFactory().getInstance();
        List<TweetView> tweets = new ArrayList<TweetView>();
        try {
            List<Status> result = twitter.getUserTimeline("atmospherian");
            for (Status s: result) {
                String source = s.getSource();
                String content = s.getText();
                tweets.add(new TweetView(source, content));
            }

        } catch (TwitterException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (tweets.size() > 0) {
            tweets = tweets.subList(0, 3);
        }

        render(testimonials, news, tweets);
    }
}

public class Security extends Secure.Security {
    static boolean authenticate(String username, String password) {
        User user = User.find("byEmail", username).first();
        return user != null && user.password.equals(Crypto.passwordHash(password));
    }

    static boolean check(String profile) {
        if ("admin".equals(profile)) {
            return User.find("byEmail", connected()).<User>first().isAdmin;
        }

        return false;
    }
}
+3
source share
2 answers

Now that we have established that you are not using @With(Secure.class)on this controller, I have a different answer. Secure checkAccessthe method is not called in this case. You can add this method to your controller:

private static void loadCookieIfPresent() {
    Http.Cookie remember = request.cookies.get("rememberme");
    if (remember != null && remember.value.indexOf("-") > 0) {
        String sign = remember.value.substring(0, remember.value.indexOf("-"));
        String username = remember.value.substring(remember.value.indexOf("-") + 1);
        if (Crypto.sign(username).equals(sign)) {
            session.put("username", username);
        }
    }
}

and call it at the beginning of your method checkUserto read the cookie without forcing a login.

+4
source

I suspect this is due to the fact that login verification is also triggered using annotations @Before, so they may be executed in the wrong order:

public class Secure extends Controller {

    @Before(unless={"login", "authenticate", "logout"})
    static void checkAccess() throws Throwable {
        // Authent
        if(!session.contains("username")) {
            flash.put("url", request.method == "GET" ? request.url : "/"); // seems a good default
            login();
        }
    ...

, @Before. - @Before checkUser homePage.

0

Source: https://habr.com/ru/post/1781862/


All Articles