/src/middleware/ewgi_session/ewgi_session_server_store.erl
Erlang | 130 lines | 87 code | 13 blank | 30 comment | 1 complexity | 7e412a7163eaf6c7a78687344a3b4533 MD5 | raw file
1%% @author Davide Marquês <nesrait@gmail.com> 2%% @copyright 2009 Davide Marquês <nesrait@gmail.com> 3%% 4%% @doc Interface for server-side session stores. 5%% 6%% This store serves as an interface for stores that manage 7%% client sessions on the server side using session_id's to 8%% between differenciate the sessions. 9%% 10%% Currently cookies are needed for the client to hold the session_id. 11%% BUT/TODO: we could also encode the session_id on the urls so it might 12%% be a good idea to swap cookie_headers/4 for a inject_session_data_on_response/? 13%% function defined on the ewgi_session module. 14%% @end 15%% 16%% Licensed under the MIT license: 17%% http://www.opensource.org/licenses/mit-license.php 18 19-module(ewgi_session_server_store). 20-author('Davide Marquês <nesrait@gmail.com>'). 21 22%% Session Store API 23-export([load_session/2, delete_session/2, store_session/2]). 24 25%% Usage examples 26-export([create_example/1, delete_example/1]). 27 28-import(ewgi_util_cookie, [cookie_headers/5, cookie_safe_encode/1, cookie_safe_decode/1]). 29 30-include("ewgi.hrl"). 31 32-define(SESSION_ID, "ewgi.session_server_store.session_id"). 33-define(SESSION_SERVER_MODULE, ewgi_session_server). 34 35%%==================================================================== 36%% Session Store API 37%%==================================================================== 38load_session(Ctx, [ServerId, CookieName, _CookiePath, _SecureCookie, Timeout, IncludeIp] = StoreArgs) -> 39 case ewgi_api:get_header_value("cookie", Ctx) of 40 undefined -> 41 ewgi_session2:new_session(Ctx); 42 Cookies -> 43 CookieValues = ewgi_util_cookie:parse_cookie(Cookies), 44 case proplists:get_value(CookieName, CookieValues) of 45 undefined -> 46 ewgi_session:new_session(Ctx); 47 SidB64 -> 48 BinSid = cookie_safe_decode(SidB64), 49 case (catch(binary_to_term(BinSid))) of 50 Sid when is_list(Sid) -> 51 Ctx1 = ewgi_api:store_data(?SESSION_ID, Sid, Ctx), 52 case ?SESSION_SERVER_MODULE:get_session(ServerId, Sid) of 53 undefined -> 54 ewgi_session:new_session(Ctx1); 55 Session -> 56 case ewgi_session:init_session(Ctx1, Session, Timeout, IncludeIp) of 57 invalid_session -> 58 %% DISPLAY ERROR!? 59 Ctx_2 = ?MODULE:delete_session(Ctx, StoreArgs), 60 ewgi_session:new_session(Ctx_2); 61 Ctx_2 -> 62 Ctx_2 63 end 64 end; 65 _ -> 66 %% DISPLAY ERROR! {?MODULE, cookie_tampered} 67 ewgi_session:new_session(Ctx) 68 end 69 end 70 end. 71 72store_session(Ctx, [ServerId, CookieName, CookiePath, SecureCookie, _Timeout, IncludeIp]) -> 73 Sid = ewgi_api:find_data(?SESSION_ID, Ctx), 74 case Sid of 75 undefined -> 76 %% New session 77 Session = ewgi_session:get_session(Ctx, IncludeIp), 78 NewId = ?SESSION_SERVER_MODULE:save_new_session(ServerId, Session), 79 SidB64 = cookie_safe_encode(term_to_binary(NewId)), 80 cookie_headers(Ctx, CookieName, SidB64, CookiePath, SecureCookie); 81 Sid -> 82 %% existing session 83 Updated = ewgi_session:session_updated(Ctx), 84 if Updated -> 85 Session = ewgi_session:get_session(Ctx, IncludeIp), 86 ?SESSION_SERVER_MODULE:save_session(ServerId, Sid, Session); 87 true -> ok %% nothing to do! 88 end, 89 Ctx 90 end. 91 92delete_session(Ctx, [ServerId, CookieName, CookiePath, SecureCookie]) -> 93 Sid = ewgi_api:find_data(?SESSION_ID, Ctx), 94 case Sid of 95 undefined -> ok; 96 _ -> ?SESSION_SERVER_MODULE:delete_session(ServerId, Sid) 97 end, 98 Ctx1 = ewgi_api:store_data(?SESSION_ID, undefined, Ctx), 99 cookie_headers(Ctx1, CookieName, [], CookiePath, SecureCookie). 100 101%%==================================================================== 102%% example functions on how to use the session middleware 103%%==================================================================== 104%% The server reference :: Pid | LocalName | {Node,Name} | {global,Name} 105-define(SESSION_SERVER_REF, ewgi_session_server). 106-define(COOKIE_PATH, "/"). 107-define(SECURE_COOKIE, false). 108-define(INCLUDE_IP, true). 109-define(SESSION_TIMEOUT, 15 * 60 * 1000). %% 15 minutes 110-define(SESSION_STORE_ARGS, [ 111 ?SESSION_SERVER_REF, 112 "server_session_id", 113 ?COOKIE_PATH, 114 ?SECURE_COOKIE, 115 ?SESSION_TIMEOUT, 116 ?INCLUDE_IP 117 ]). 118 119create_example(Ctx) -> 120 SessionApp = fun ewgi_session:session_create_app/1, 121 Ctx1 = ?MODULE:load_session(Ctx, ?SESSION_STORE_ARGS), 122 Ctx2 = SessionApp(Ctx1), 123 ?MODULE:store_session(Ctx2, ?SESSION_STORE_ARGS). 124 125delete_example(Ctx) -> 126 SessionApp = fun ewgi_session:session_delete_app/1, 127 Ctx1 = ?MODULE:load_session(Ctx, ?SESSION_STORE_ARGS), 128 Ctx2 = SessionApp(Ctx1), 129 ?MODULE:store_session(Ctx2, ?SESSION_STORE_ARGS). 130