[CZĘŚĆ 1]: Sesja PRZEDMIOT
żądanie http przetwarza się oddzielnie, tak więc w celu utrzymania informacji między każdym zapytaniu (na przykład, informacje o użytkowniku), obiekt sesji musi być tworzone na serwerze.
Niektóre witryny w ogóle nie wymagają sesji. Witryna, na której użytkownicy nie mogą modyfikować żadnych treści, nie będzie musiała zarządzać sesją (na przykład CV online). Nie potrzebujesz żadnego pliku cookie ani sesji na takiej stronie internetowej.
Tworzenie sesji:
W serwletu, użyj metody request.getSession(true)
z HttpServletRequest obiektu, aby utworzyć nowy obiekt HttpSession. Zauważ, że jeśli użyjesz request.getSession(false)
, null zostanie zwrócona, jeśli sesja nie została jeszcze utworzona. Look at this answer for more details.
Set/Get atrybuty:
Celem sesji jest, aby zachować informacje na stronie serwera pomiędzy każdą prośbę. Na przykład, zachowując nazwę użytkownika:
session.setAttribute("name","MAGLEFF");
// Cast
String name = (String) session.getAttribute("name");
Destroy sesję:
sesja zostanie automatycznie zniszczony, jeśli są przechowywane nieaktywną zbyt wiele czasu. Look at this answer for more details. Ale można ręcznie wymusić sesja zostać zniszczone, w przypadku działania wylogowania na przykład:
HttpSession session = request.getSession(true);
session.invalidate();
[CZĘŚĆ 2]: Więc ... przyłączyć się do ciemnej strony mamy ciastka?
Nadchodzi ciasteczka.
JSESSIONID:
JSESSIONID cookies jest tworzony na komputerze użytkownika za każdym razem, gdy sesja jest tworzony z request.getSession()
. Czemu? Ponieważ każda sesja utworzona po stronie serwera ma identyfikator. Nie możesz uzyskać dostępu do sesji innego użytkownika, chyba że nie masz prawidłowego identyfikatora. Ten identyfikator jest przechowywany w pliku cookie JSESSIONID i umożliwia użytkownikowi znalezienie jego informacji. Look at this answer for more details!
Kiedy usuwa się JSESSIONID?
JSESSIONID nie ma datę ważności: to ciasteczko sesja. Podobnie jak wszystkie pliki cookie sesji, zostanie ona usunięta po zamknięciu przeglądarki. Jeśli użyjesz podstawowego mechanizmu JSESSIONID, sesja stanie się nieosiągalna po zamknięciu i ponownym otwarciu przeglądarki, ponieważ plik cookie JSESSIONID zostanie usunięty.
Należy pamiętać, że sesja jest nieosiągalna dla klienta, ale nadal działa po stronie serwera. Ustawienie opcji MaxInactiveIntervalpozwala serwerowi automatycznie unieważnić sesję, gdy była nieaktywna przez zbyt długi czas.
Zło zniszczenie JSESSIONID
Tak dla zabawy, pewnego dnia znalazłem ten kod na projekcie. Był używany do unieważnienia sesji usuwając cookie JSESSIONID z javascript:
<SCRIPT language="JavaScript" type="text/javascript">
function delete_cookie(check_name) {
// first we'll split this cookie up into name/value pairs
// note: document.cookie only returns name=value, not the other components
var a_all_cookies = document.cookie.split(';');
var a_temp_cookie = '';
var cookie_name = '';
var cookie_value = '';
var b_cookie_found = false; // set boolean t/f default f
// var check_name = 'JSESSIONID';
var path = null;
for (i = 0; i < a_all_cookies.length; i++)
{
// now we'll split apart each name=value pair
a_temp_cookie = a_all_cookies[i].split('=');
// and trim left/right whitespace while we're at it
cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
// alert (cookie_name);
// if the extracted name matches passed check_name
if (cookie_name.indexOf(check_name) > -1)
{
b_cookie_found = true;
// we need to handle case where cookie has no value but exists (no = sign, that is):
if (a_temp_cookie.length > 1)
{
cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, ''));
document.cookie = cookie_name + "=" + cookie_value +
";path=/" +
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
// alert("cookie deleted " + cookie_name);
}
}
a_temp_cookie = null;
cookie_name = '';
}
return true;
}
// DESTROY
delete_cookie("JSESSIONID");
</SCRIPT>
Give another look to this answer. W JavaScript, JSESSIONID można odczytać, zmodyfikować, utracić lub przejąć sesję.
[CZĘŚĆ 3]. Prowadzenie sesję po zamykania przeglądarki
Po zamkniętym i ponownym otwarciu przeglądarki, a ich rachunki są nadal podpisana w ale niektóre strony internetowe, nie można zrobić tak . Jestem zdezorientowany, że jest to sesja lub plik cookie ??
To ciasteczko.
Widzieliśmy, że po usunięciu pliku cookie sesji JSESSIONID przez przeglądarkę internetowa obiekt sesji po stronie serwera zostanie utracony. Nie można uzyskać do niego dostępu bez odpowiedniego identyfikatora.
Jeśli chcę moja strona ma zostać podpisana w tym stylu, muszę ustawić session.setMaxInactiveInterval() lub cookie.setMaxAge()?
Zobaczyliśmy również, że session.setMaxInactiveInterval()
było zapobiec niekończącej się utracie sesji. JSESSIONID cookie cookie.setMaxAge()
nigdzie nas nie dostanie.
Użyj persistent cookies z Session ID:
doszedłem do tego rozwiązania po przeczytaniu następujące tematy:
Główną ideą jest zarejestrowanie sesji użytkownika w mapie, umieszczonej w kontekście serwletu. Za każdym razem, gdy tworzona jest sesja, jest ona dodawana do mapy z wartością JSESSIONID dla klucza; Trwały plik cookie jest również tworzony w celu zapamiętania wartości JSESSIONID, aby znaleźć sesję po zniszczeniu pliku cookie JSESSIONID.
Po zamknięciu przeglądarki JSESSIONID ulega zniszczeniu. Jednak wszystkie adresy obiektów HttpSession zostały zapisane w Mapie po stronie serwera i można uzyskać dostęp do właściwej sesji z wartością zapisaną w trwałym pliku cookie.
Najpierw dodaj dwa detektory w deskryptorze wdrożenia web.xml.
<listener>
<listener-class>
fr.hbonjour.strutsapp.listeners.CustomServletContextListener
</listener-class>
</listener>
<listener>
<listener-class>
fr.hbonjour.strutsapp.listeners.CustomHttpSessionListener
</listener-class>
</listener>
CustomServletContextListener tworzy mapę przy inicjalizacji kontekstu. Ta mapa zarejestruje wszystkie sesje utworzone przez użytkownika w tej aplikacji.
/**
* Instanciates a HashMap for holding references to session objects, and
* binds it to context scope.
* Also instanciates the mock database (UserDB) and binds it to
* context scope.
* @author Ben Souther; [email protected]
* @since Sun May 8 18:57:10 EDT 2005
*/
public class CustomServletContextListener implements ServletContextListener{
public void contextInitialized(ServletContextEvent event){
ServletContext context = event.getServletContext();
//
// instanciate a map to store references to all the active
// sessions and bind it to context scope.
//
HashMap activeUsers = new HashMap();
context.setAttribute("activeUsers", activeUsers);
}
/**
* Needed for the ServletContextListener interface.
*/
public void contextDestroyed(ServletContextEvent event){
// To overcome the problem with losing the session references
// during server restarts, put code here to serialize the
// activeUsers HashMap. Then put code in the contextInitialized
// method that reads and reloads it if it exists...
}
}
CustomHttpSessionListener położy sesję na mapie activeUsers gdy jest on tworzony.
/**
* Listens for session events and adds or removes references to
* to the context scoped HashMap accordingly.
* @author Ben Souther; [email protected]
* @since Sun May 8 18:57:10 EDT 2005
*/
public class CustomHttpSessionListener implements HttpSessionListener{
public void init(ServletConfig config){
}
/**
* Adds sessions to the context scoped HashMap when they begin.
*/
public void sessionCreated(HttpSessionEvent event){
HttpSession session = event.getSession();
ServletContext context = session.getServletContext();
HashMap<String, HttpSession> activeUsers = (HashMap<String, HttpSession>) context.getAttribute("activeUsers");
activeUsers.put(session.getId(), session);
context.setAttribute("activeUsers", activeUsers);
}
/**
* Removes sessions from the context scoped HashMap when they expire
* or are invalidated.
*/
public void sessionDestroyed(HttpSessionEvent event){
HttpSession session = event.getSession();
ServletContext context = session.getServletContext();
HashMap<String, HttpSession> activeUsers = (HashMap<String, HttpSession>)context.getAttribute("activeUsers");
activeUsers.remove(session.getId());
}
}
Użyj podstawową formę przetestować uwierzytelnienia użytkownika za pomocą nazwy użytkownika/hasła. Ten formularz login.jsp jest przeznaczony wyłącznie do testów.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title><bean:message key="formulaire1Title" /></title>
</head>
<body>
<form action="login.go" method="get">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" />
</form>
</body>
</html>
Idziemy. Ten serwlet Java przekazuje stronę logowania, gdy użytkownik nie jest w sesji, i do innej strony, gdy jest. Jest przeznaczony tylko do testowania trwałej sesji!
public class Servlet2 extends AbstractServlet {
@Override
protected void doGet(HttpServletRequest pRequest,
HttpServletResponse pResponse) throws IOException, ServletException {
String username = (String) pRequest.getParameter("username");
String password = (String) pRequest.getParameter("password");
// Session Object
HttpSession l_session = null;
String l_sessionCookieId = getCookieValue(pRequest, "JSESSIONID");
String l_persistentCookieId = getCookieValue(pRequest, "MY_SESSION_COOKIE");
// If a session cookie has been created
if (l_sessionCookieId != null)
{
// If there isn't already a persistent session cookie
if (l_persistentCookieId == null)
{
addCookie(pResponse, "MY_SESSION_COOKIE", l_sessionCookieId, 1800);
}
}
// If a persistent session cookie has been created
if (l_persistentCookieId != null)
{
HashMap<String, HttpSession> l_activeUsers = (HashMap<String, HttpSession>) pRequest.getServletContext().getAttribute("activeUsers");
// Get the existing session
l_session = l_activeUsers.get(l_persistentCookieId);
}
// Otherwise a session has not been created
if (l_session == null)
{
// Create a new session
l_session = pRequest.getSession();
}
//If the user info is in session, move forward to another page
String forward = "/pages/displayUserInfo.jsp";
//Get the user
User user = (User) l_session.getAttribute("user");
//If there's no user
if (user == null)
{
// Put the user in session
if (username != null && password != null)
{
l_session.setAttribute("user", new User(username, password));
}
// Ask again for proper login
else
{
forward = "/pages/login.jsp";
}
}
//Forward
this.getServletContext().getRequestDispatcher(forward).forward(pRequest, pResponse);
}
MY_SESSION_COOKIE cookie będzie zapisać wartość cookie JSESSIONID. Kiedy plik cookie JSESSIONID zostanie zniszczony, MY_SESSION_COOKIE nadal istnieje z identyfikatorem sesji.
JSESSIONID zniknął z sesji przeglądarki internetowej, ale zdecydowaliśmy się użyć trwałego i prostego pliku cookie, wraz z mapą wszystkich aktywnych sesji umieszczonych w kontekście aplikacji. Trwałe ciasteczko pozwala nam znaleźć odpowiednią sesję na mapie.
Nie zapomnij tych użytecznych metod dokonane przez BalusC dodawać/get/usuń pliki cookie:
/**
*
* @author BalusC
*/
public static String getCookieValue(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return null;
}
/**
*
* @author BalusC
*/
public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
/**
*
* @author BalusC
*/
public static void removeCookie(HttpServletResponse response, String name) {
addCookie(response, name, null, 0);
}
}
Ostatnim rozwiązaniem był testowany z GlassFish na localhost, chromem na przeglądarce internetowej, na oknach. To zależy tylko od jednego pliku cookie i nie potrzebujesz bazy danych. Ale właściwie nie wiem, jakie są ograniczenia takiego mechanizmu.Spędziłem tylko noc przychodząc do tego rozwiązania, nie wiedząc, czy to będzie dobre, czy złe.
DZIĘKI
wciąż się uczę, proszę mi powiedzieć, czy jest jakiś błąd w mojej odpowiedzi. Dzięki, @ +
Duplikat [Jak mogę przechowywać zalogowanego użytkownika na mojej stronie przez wiele miesięcy?] (Http://stackoverflow.com/questions/2185951/java-how-do-i-keep-a-user-logged-into -my-site-for-months) – BalusC
Związane z tym: http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading/3106909#3106909 – BalusC
Przeczytaj ten OWASP [ściągnij arkusz] (https://www.owasp.org/index.php/Session_Management_Cheat_Sheet). To bardzo miłe odniesienie. – Hong