webmachine and redirect unauthenticated users

958 views Asked by At

In my new project I want to use webmachine and mochiweb. First thing i want to do is authentication.

I edit "dispatch.conf" and make some resources, like:

{["auth"], my_res_auth, []}.
{["protected"], my_res_protected, []}.
{['*'], my_res_default, []}.

When some one access "protected" resource i want to redirect him to "auth" resource if he not logged in. "auth" resource contains web form with user name and password, it do all auth work.

I put such code inside of my_res_protected.erl:

is_authorized(ReqData, State) ->
    case my_auth:is_authorized(ReqData) of
        true -> {true, ReqData, State};
        false ->
            % here should be something to redirect user to "auth" resource
            % currently i put such thing, which is incorrect:
            {true, wrq:do_redirect(true, wrq:set_resp_header("location", "/auth", ReqData)), State}
            % dont know what should i put instead of "true"
    end.

i googled some example of how to do it, but dont like that i should have to put this functions in all resources, which requires auth.

Is there any way to do it?

2

There are 2 answers

0
garry On

In the case where you're not authorized and do_redirect is false, why not just return { false, ReqData, State } like webmachine expects for is_authorized(), instead of constructing the response yourself?

2
danechkin On

i think i found right way, put this code into auth.hrl file and include it in my resources

is_authorized(ReqData, State) ->
    case my_auth:is_authorized(ReqData) of
        true -> {true, ReqData, State};
        false ->
            % there i got address, to which should i redirect
            % this address is defined in dispatch.conf
            % and walk trough my_res_protected:init/1 into State
            case proplists:get_value(do_redirect, State, false) of
                false ->
                    {{halt, 401}, wrq:set_resp_header(
                            "Content-type", "text/plain",
                            wrq:set_resp_body("NOT AUTHORIZED", ReqData)
                        ), State};
                Location ->
                    {{halt, 302}, wrq:set_resp_header("Location", Location, ReqData), State}
            end
    end.