首頁 web前端 js教程 使用cookie保持登入狀態步驟詳解

使用cookie保持登入狀態步驟詳解

May 22, 2018 am 10:59 AM
cookie ie 狀態

這次帶給大家使用cookie保持登入狀態步驟詳解,使用cookie保持登入狀態的注意事項有哪些,以下就是實戰案例,一起來看一下。

這次來做一個網站登入的小例子,後面會用到。這個範例會用到Cookie、HTML表單、POST資料體(body)解析。

第一個版本,我們的使用者資料就寫死在js檔案裡。第二個版本會引入MongoDB來保存使用者資料。

範例準備

1. 使用express建立應用

就下面的指令序列:

express LoginDemo
cd LoginDemo
npm install
登入後複製

2. 登入頁面

登入頁面的jade範本為login.jade,內容如下:

doctype html
html
 head
  meta(charset='UTF-8')
  title 登录
  link(rel='stylesheet', href='/stylesheets/login.css')
 body
  .form-container
   p.form-header 登录
   form(action='login', method='POST', align='center')
    table
     tr
      td
       label(for='user') 账号:
      td
       input#user(type='text', name='login_username')
     tr
      td
       label(for='pwd') 密码:
      td
       input#pwd(type='password', name='login_password')
     tr
      td(colspan='2', align='right')
       input(type='submit', value='登录')
  p #{msg}
登入後複製

login.jade放在views目錄下。我在login.jade裡硬編碼了漢字,注意檔案用UTF-8編碼。

這個範本的最後是一條動態訊息,用來顯示登入錯誤訊息,msg變數由應用程式傳入。

我給login頁面寫了個簡單的CSS,login.css文件,內容如下:

form {
 margin: 12px;
}
a {
 color: #00B7FF;
}
p.form-container {
 display: inline-block;
 border: 6px solid steelblue;
 width: 280px;
 border-radius: 10px;
 margin: 12px;
}
p.form-header {
 margin: 0px;
 font: 24px bold;
 color: white;
 background: steelblue;
 text-align: center;
}
input[type=submit]{
 font: 18px bold;
 width: 120px;
 margin-left: 12px;
}
登入後複製

請把login.css放在public/stylesheets目錄下。

3. profile頁面

##登入成功後會顯示設定頁面,profile.jade頁面內容:

doctype html
html
 head
  meta(charset='UTF-8')
  title= title
 body
  p #{msg}
  p #{lastTime}
  p 
   a(href='/logout') 退出
登入後複製
profile.jade放在views目錄下。 profile頁面顯示一則登入成功的訊息,也顯示上次登入時間,最後提供了退出連結。

4. app.js改變

我改動了app.js,以便使用者在沒有登入時造訪網站自動跳到login頁面。新的app.js內容如下:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(dirname, 'public')));
app.all('*', users.requireAuthentication);
app.use('/', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
 var err = new Error('Not Found');
 err.status = 404;
 next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
 app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
   message: err.message,
   error: err
  });
 });
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
 res.status(err.status || 500);
 res.render('error', {
  message: err.message,
  error: {}
 });
});
module.exports = app;
登入後複製

5. users.js

我修改了users.js,把認證、登入、登出等邏輯放在裡面,首先要把users.js轉為UTF-8編碼(sorry,硬編碼了漢字哈)。內容:

var express = require('express');
var router = express.Router();
var crypto = require('crypto');
function hashPW(userName, pwd){
 var hash = crypto.createHash('md5');
 hash.update(userName + pwd);
 return hash.digest('hex');
}
// just for tutorial, it's bad really
var userdb = [
  {
   userName: "admin",
   hash: hashPW("admin", "123456"),
   last: ""
  },
  {
   userName: "foruok",
   hash: hashPW("foruok", "888888"),
   last: ""
  }
 ];
function getLastLoginTime(userName){
 for(var i = 0; i < userdb.length; ++i){
  var user = userdb[i];
  if(userName === user.userName){
   return user.last;
  }
 }
 return "";
}
function updateLastLoginTime(userName){
 for(var i = 0; i < userdb.length; ++i){
  var user = userdb[i];
  if(userName === user.userName){
   user.last = Date().toString();
   return;
  }
 }
}
function authenticate(userName, hash){
 for(var i = 0; i < userdb.length; ++i){
  var user = userdb[i];
  if(userName === user.userName){
   if(hash === user.hash){
     return 0;
   }else{
     return 1;
   }
  }
 }
 return 2;
}
function isLogined(req){
 if(req.cookies["account"] != null){
  var account = req.cookies["account"];
  var user = account.account;
  var hash = account.hash;
  if(authenticate(user, hash)==0){
   console.log(req.cookies.account.account + " had logined.");
   return true;
  }
 }
 return false;
};
router.requireAuthentication = function(req, res, next){
 if(req.path == "/login"){
  next();
  return;
 }
 if(req.cookies["account"] != null){
  var account = req.cookies["account"];
  var user = account.account;
  var hash = account.hash;
  if(authenticate(user, hash)==0){
   console.log(req.cookies.account.account + " had logined.");
   next();
   return;
  }
 }
 console.log("not login, redirect to /login");
 res.redirect('/login?'+Date.now());
};
router.post('/login', function(req, res, next){
 var userName = req.body.login_username;
 var hash = hashPW(userName, req.body.login_password);
 console.log("login_username - " + userName + " password - " + req.body.login_password + " hash - " + hash);
 switch(authenticate(userName, hash)){
 case 0: //success
  var lastTime = getLastLoginTime(userName);
  updateLastLoginTime(userName);
  console.log("login ok, last - " + lastTime);
  res.cookie("account", {account: userName, hash: hash, last: lastTime}, {maxAge: 60000});
  res.redirect('/profile?'+Date.now());
  console.log("after redirect");
  break;
 case 1: //password error
  console.log("password error");
  res.render('login', {msg:"密码错误"});
  break;
 case 2: //user not found
  console.log("user not found");
  res.render('login', {msg:"用户名不存在"});
  break;
 }
});
router.get('/login', function(req, res, next){
 console.log("cookies:");
 console.log(req.cookies);
 if(isLogined(req)){
  res.redirect('/profile?'+Date.now());
 }else{
  res.render('login');
 }
});
router.get('/logout', function(req, res, next){
 res.clearCookie("account");
 res.redirect('/login?'+Date.now());
});
router.get('/profile', function(req, res, next){
 res.render('profile',{
  msg:"您登录为:"+req.cookies["account"].account, 
  title:"登录成功",
  lastTime:"上次登录:"+req.cookies["account"].last
 });
});
module.exports = router;
登入後複製
如你所見,我內建了兩個帳號,admin和foruok,登入時就驗證這兩個帳號,不對就報錯。

好了,執行“npm start”,然後在瀏覽器中開啟“http://localhost:3000”,可以看到下面的效果:

折騰幾次,登錄,退出,再次登錄,效果如下:

#好啦,這就是這個範例的效果。接下來我們來解釋一下用到概念和部分程式碼。

處理POST正文資料

我們在範例中使用了HTML表單來接收使用者名稱和密碼,當input元素的類型為submit時,點選它,瀏覽器會把表單內的資料以一定的格式組織之後編碼進body,POST到指定的伺服器位址。使用者名稱和密碼,在伺服器端,可以透過

HTML元素的名字屬性的值找出來。

伺服器解析表單資料這個過程,我們不用擔心,用了express的body-parser中間件,它會幫我們做這件事,只要做簡單的設定即可。而且這些設定碼,express generator都幫我們完成了,如下:

//加载body-parser模块
var bodyParser = require('body-parser');
...
//应用中间件
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
登入後複製
我們處理/login路徑上的POST請求的程式碼在users.js裡,從「router.post('/login'… 「開始(94行,如果markdown能自動給程式碼插入行號就好了)。引用登入表單內的使用者名稱的程式碼如下:

var userName = req.body.login_username;
登入後複製
注意到了吧,express.Request物件req內有解析好的body,我們使用login_username來存取使用者名稱。

#

cookie,按我的理解,就是服务器发给浏览器的一张门票,要访问服务器内容,可以凭票入场,享受某种服务。服务器可以在门票上记录一些信息,从技术角度讲,想记啥记啥。当浏览器访问服务器时,HTTP头部把cookie信息带到服务器,服务器解析出来,校验当时记录在cookie里的信息。

HTTP协议本身是无状态的,而应用服务器往往想保存一些状态,cookie应运而生,由服务器颁发,通过HTTP头部传给浏览器,浏览器保存到本地。后续访问服务器时再通过HTTP头部传递给服务器。这样的交互,服务器就可以在cookie里记录一些用户相关的信息,比如是否登录了,账号了等等,然后就可以根据这些信息做一些动作,比如我们示例中的持久登录的实现,就利用了cookie。还有一些电子商务网站,实现购物车时也可能用到cookie。

cookie存储的是一些key-value对。在express里,Request和Response都有cookie相关的方法。Request实例req的cookies属性,保存了解析出的cookie,如果浏览器没发送cookie,那这个cookies对象就是一个空对象。

express有个插件,cookie-parser,可以帮助我们解析cookie。express生成的app.js已经自动为我们配置好了。相关代码:

var cookieParser = require('cookie-parser');
...
app.use(cookieParser());
登入後複製

express的Response对象有一个cookie方法,可以回写给浏览器一个cookie。

下面的代码发送了一个名字叫做“account”的cookie,这个cookie的值是一个对象,对象内有三个属性。

复制代码 代码如下:

res.cookie("account", {account: userName, hash: hash, last: lastTime}, {maxAge: 60000});

res.cookie()方法原型如下:

res.cookie(name, value [, options])
登入後複製

文档在这里:http://expressjs.com/4x/api.html。

浏览器会解析HTTP头部里的cookie,根据过期时间决定保存策略。当再次访问服务器时,浏览器会把cookie带给服务器。服务器使用cookieParser解析后保存在Request对象的cookies属性里,req.cookies本身是一个对象,解析出来的cookie,会被关联到req.cookies的以cookie名字命名的属性上。比如示例给cookie起的名字叫account,服务端解析出的cookie,就可以通过req.cookies.account来访问。注意req.cookies.account本身既可能是简单的值也可能是一个对象。在示例中通过res.cookie()发送的名为account的cookie,它的值是一个对象,在这种情况下,服务器这边从HTTP请求中解析出的cookie也会被组装成一个对象,所以我们通过req.cookies.account.account就可以拿到浏览器通过cookie发过来的用户名。但如果浏览器没有发送名为“account”的cookie,那req.cookies.account.hash这种访问就会抛异常,所以我在代码里使用req.cookies[“account”]这种方式来检测是否有account这个cookie。

持久登录

如果用户每次访问一个需要鉴权的页面都要输入用户名和密码来登录,那就太麻烦了。所以,很多现代的网站都实现了持久登录。我的示例使用cookie简单实现了持久登录。

在处理/login路径上的POST请求时,如果登录成功,就把用户名、一个hash值、还有上次登录时间保存在cookie里,并且设置cookie的有效期为60秒。这样在60秒有效期内,浏览器后续的访问就会带cookie,服务端代码从cookie里验证用户名和hash值,让用户保持登录状态。当过了60秒,浏览器就不再发送cookie,服务端就认为需要重新登录,将用户重定向到login页面。

现在服务端的用户信息就简单的放在js代码里了,非常丑陋,下次我们引入MongoDB,把用户信息放在数据库里。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Node.js Express安装与使用步骤详解

table表格内对某列内容进行搜索筛选步骤详解

以上是使用cookie保持登入狀態步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

處於待機狀態的連線狀態:已斷開,原因:NIC合規性 處於待機狀態的連線狀態:已斷開,原因:NIC合規性 Feb 19, 2024 pm 03:15 PM

「事件日誌訊息中的連接狀態顯示為待機狀態:已斷開連接,原因是符合NIC標準。這表示系統在待機模式下,網路介面卡(NIC)已斷開連接。雖然這通常是網路問題,但也可能由軟體和硬體衝突引起。在接下來的討論中,我們將探討如何解決這個問題。」待機連接斷開的原因是什麼? NIC合規性?如果在Windows事件檢視器中發現「ConnectivityStatusinStandby:DisConnected,Reason:NICCompliance」訊息,這表示您的NIC或網路介面控制器可能有問題。這種情況通常

cookie存在哪裡 cookie存在哪裡 Dec 20, 2023 pm 03:07 PM

Cookie通常儲存在瀏覽器的Cookie資料夾中的,瀏覽器中的Cookie檔案通常以二進位或SQLite格式存儲,如果直接開啟Cookie文件,可能會看到一些亂碼或無法讀取的內容,因此最好使用瀏覽器提供的Cookie管理介面來檢視和管理Cookie。

陌陌狀態怎麼設定 陌陌狀態怎麼設定 Mar 01, 2024 pm 12:10 PM

陌陌這款廣為人知的社群平台,為用戶的日常社交提供了豐富的功能服務。在陌陌上,用戶可以輕鬆分享生活狀態、結交朋友、進行聊天等。其中設定狀態功能讓使用者能夠向其他展示自己當前的心情和狀態,進而吸引更多人的注意和交流。那麼究竟該如何設定自己的陌陌狀態呢,以下就為大家帶來詳細的內容介紹!陌陌怎麼設定狀態? 1.打開陌陌,點擊右下角更多,找到並點擊每日狀態。 2、選擇狀態。 3、即可顯示設定的狀態。

電腦上的cookie在哪裡 電腦上的cookie在哪裡 Dec 22, 2023 pm 03:46 PM

電腦上的Cookie儲存在瀏覽器的特定位置,具體位置取決於使用的​​瀏覽器和作業系統:1、Google Chrome, 儲存在C:\Users\YourUsername\AppData\Local\Google\Chrome\User Data\Default \Cookies中等等。

如何查看伺服器狀態 如何查看伺服器狀態 Oct 09, 2023 am 10:10 AM

查看伺服器狀態的方法有使用命令列工具、圖形介面工具、監控工具、日誌檔案和遠端管理工具等。詳細介紹:1、使用命令列工具,在Linux或Unix伺服器上,可以使用命令列工具來查看伺服器的狀態;2、使用圖形介面工具,對於具有圖形介面的伺服器作業系統,可以使用系統提供的圖形介面工具來查看伺服器狀態;3、使用監控工具,可以使用專門的監控工具來即時監視伺服器的狀態等等。

手機cookie在哪裡 手機cookie在哪裡 Dec 22, 2023 pm 03:40 PM

手機上的Cookie儲存在行動裝置的瀏覽器應用程式中:1、在iOS裝置上,Cookie儲存在Safari瀏覽器的Settings -> Safari -> Advanced -> Website Data中;2、在Android裝置上,Cookie儲存在Chrome瀏覽器的Settings -> Site settings -> Cookies中等等。

Cookie工作原理是什麼 Cookie工作原理是什麼 Sep 20, 2023 pm 05:57 PM

Cookie運作方式涉及到伺服器發送Cookie、瀏覽器儲存Cookie以及瀏覽器對Cookie的處理和儲存。詳細介紹:1、伺服器發送Cookie,伺服器會傳送一個包含Cookie的HTTP回應標頭給瀏覽器。這個Cookie包含了一些訊息,例如使用者的身份認證、偏好設定或購物車內容等,瀏覽器接收到這個Cookie後,會將它儲存在使用者的電腦上;2、瀏覽器儲存Cookie等等。

清除cookie有什麼影響嗎 清除cookie有什麼影響嗎 Sep 20, 2023 pm 06:01 PM

清除cookie產生的影響有重置個人化設定和偏好、影響廣告體驗、破壞登入狀態和記住密碼功能。詳細介紹:1、重置個人化設定和偏好,如果清除了cookie,購物車將被重置為空,需要重新添加商品,同樣清除cookie還會導致在社群媒體平台上的登入狀態遺失,需要重新輸入使用者名稱和密碼;2、影響廣告體驗,如果清除了cookie,網站將無法了解我們的興趣和偏好,會顯示無關的廣告等等。

See all articles