日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

应该怎么做一个登录功能?

發(fā)布時(shí)間:2024/4/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 应该怎么做一个登录功能? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

版權(quán)是我的,轉(zhuǎn)載沒有通過我的同意的爬蟲都是傻逼.

假設(shè)有user表.里面有id,acount(賬戶,nvarchar(50)),pwd(密碼,nvarchar(50)).

最簡(jiǎn)單的實(shí)現(xiàn)

渣渣說做個(gè)登錄功能,那還不簡(jiǎn)單.

select * from user where ?acount=XX AND PWD =YY;

然而,某天,我們需要在登錄的時(shí)候更新最后登錄時(shí)間,也就是在user表里面加個(gè)lastLoginTime.

這時(shí)渣渣說

select id from user wher acount=XX AND PWD =YY;

update?user set XXXX where id=@id;

然后就他就被打了.實(shí)際上,可以合為一句:

update?user set XXXX where?acount=XX AND PWD =YY;

受影響行數(shù)大于0表示登錄成功.

密碼的加密

某一天,渣渣看到某某數(shù)據(jù)庫(kù)被下載了.想到自己的數(shù)據(jù)庫(kù)如果泄露了怎么辦,上面全是明文.

于是他就開始想加密這個(gè)事.

1MD5(同一個(gè)密碼,MD5還是一樣的,所以否決了)

2des(用于可逆密碼加密解密,然而有些安全系數(shù)要求高的密碼是不能被解密的,所以有適用范圍)

3隨機(jī)加鹽HASH.

第三種方案,要加在原來的表加多一個(gè)salt列.

每一次的登錄的話,

應(yīng)該是select *??from user wher acount=XX?

然后把里面的鹽加上輸入的密碼進(jìn)行hash然后與數(shù)據(jù)庫(kù)的加密后pwd進(jìn)行比較.比如string.equal(MD(pwd+salt),pwd)

true當(dāng)然就是說輸入正確啦.

其實(shí)加密的方案我舉的都只是最簡(jiǎn)單的例子.對(duì)于鹽的把握,大家開腦洞自己想吧.

(比如可以對(duì)原密碼進(jìn)行md5,然后對(duì)于md5的每一個(gè)偶數(shù)位字符插入鹽的一個(gè)字符,從而最后組成一個(gè)不明所以的字符串)

"無驗(yàn)證碼登錄"

我們?yōu)槭裁葱枰?yàn)證碼呢?是為了防止被密碼爆破.

那么是否可以無驗(yàn)證碼登錄呢?當(dāng)然可以.

遍地開花的開放平臺(tái)接口

比如支付寶,旺旺,qq,微博....

以qq為例.他的步驟無非就是,跳到一個(gè)指向自己應(yīng)用的騰訊鏈接.用戶在那上面授權(quán)給這個(gè)應(yīng)用.授權(quán)后返回token和openid給網(wǎng)站.

做過微信第三方服務(wù)器的人就知道,這個(gè)token是用來以授權(quán)者的名義做各種操作的,實(shí)際上,對(duì)于登錄,只要有這個(gè)openid,去數(shù)據(jù)庫(kù)檢索成功了,就應(yīng)該視為登錄有效.所以token其實(shí)沒啥用.

可信狀態(tài)下不需要驗(yàn)證碼

固定的上網(wǎng)行為

我們應(yīng)該怎么定義什么樣的狀態(tài)算作穩(wěn)定?比如,我單個(gè)用戶,連續(xù)10次的登錄有9次都是在同一個(gè)ip上登錄,那么這個(gè)ip的實(shí)際來源就應(yīng)該視為可信的狀態(tài).

固定的上網(wǎng)行為其實(shí)還有很多種,比如登錄的時(shí)間段眾數(shù),登錄的頻率,習(xí)慣使用的瀏覽器.只要你想的周全了,其實(shí)有很多用戶細(xì)節(jié)可以捕捉.

不頻繁的操作

我們相信這個(gè)世界的人大體都是美好的,所以你一看到我這個(gè)網(wǎng)站,要登錄的時(shí)候我就需要你輸入驗(yàn)證碼,但如果你連續(xù)數(shù)次密碼錯(cuò)誤,那我就要懷疑你的人品,給你下套.具體的可以看新浪微博.

場(chǎng)景的變換

不明公共wifi

我們知道http 下,明文post上去的明文被截取了就能分分鐘拿到信息.所以https就登場(chǎng)了.我post的密文就算給你看了,你也解密不了,耶~

然而這并沒有卵用.https證書根據(jù)不同的級(jí)別收不同的錢.于是12306自己做了個(gè)證書,哈哈.如果你們有魄力教導(dǎo)用戶安裝自己做的證書,那就走這條路吧....

移動(dòng)端(Android,iPhone)

這就是我最近遇到的一個(gè)比較蛋疼的問題.我們知道url有長(zhǎng)度限制,并且參數(shù)還得(utf-8)編碼.所以合適的做法應(yīng)該是可解密的json密文作為http請(qǐng)求報(bào)文的body傳上去.

然而.net環(huán)境的des默認(rèn)工作模式是cbc,所以其他客戶端也應(yīng)該用cbc進(jìn)行加密/解析.java的默認(rèn)實(shí)現(xiàn)不是cbc,而且它的偏移向量每次都隨機(jī).所以加密的結(jié)果和c#不一樣.

這里引用s站的說法,中文意思就是java的des是ecb而.NET的是cdc.工作模式不一樣.并且,我發(fā)現(xiàn)一些java 的des實(shí)現(xiàn)是用隨機(jī)向量的,所以變量不一致的話結(jié)果也會(huì)和.net的不一樣.

SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. (JCA Doc)

In .Net, The default operation mode for the symmetric algorithm is CipherMode.CBC and default padding is PaddingMode.PKCS7. (msdn..SymmetricAlgorithm)

?

/// <summary>/// DES加密字符串/// </summary>/// <param name="encryptString">待加密的字符串</param>/// <param name="key"></param>/// <returns>加密成功返回加密后的字符串,失敗返回源串</returns>public static string DESEncrypt(this string encryptString, string key){try{if (key.Length < 8)throw new ArgumentException("密鑰和向量必須為8位,否則加密解密都不成功", "key");byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8));byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);using (var dCSP = new DESCryptoServiceProvider()){using (MemoryStream mStream = new MemoryStream()){using (var cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbKey), CryptoStreamMode.Write)){cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();cStream.Close();return Convert.ToBase64String(mStream.ToArray());}}}}catch{return encryptString;}}

  這下面是哥用了2015年7月3日用了0.7個(gè)下午的時(shí)間研(抄)究(襲)出來的java加密代碼

import java.util.HashMap; import java.util.Map;import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.SecretKeySpec;import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.Security;import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec;import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec;import net.sf.json.JSONArray; import net.sf.json.JSONObject; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;public static void main(String[] args) throws Exception {Map map = new HashMap(); map.put( "Msg", "哦" ); map.put( "Url", "oooo"); JSONObject jsonObject = JSONObject.fromObject( map ); String shit=jsonObject.toString();System.out.println(shit); System.out.println(encrypt(shit,"UTF8"));}public static String encrypt(String message,String encoding,String myKey) throws Exception { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(myKey.getBytes(encoding)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(myKey.getBytes(encoding)); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] buf = cipher.doFinal(message.getBytes(encoding)); sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();String a = encoder.encode(buf);return a; }

這是哥移植到安卓的代碼,只是最后的base64用了Android的類,其余無區(qū)別

import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; public static String encrypt(String key, String message, String encoding) throws Exception {Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(encoding));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(desKeySpec);IvParameterSpec iv = new IvParameterSpec(key.getBytes(encoding));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] buf = cipher.doFinal(message.getBytes(encoding)); return android.util.Base64.encodeToString(buf, android.util.Base64.DEFAULT);
}

  

ios(object c)的我不知道,但是同事告訴我,轉(zhuǎn)成的base64除了大小寫有細(xì)微的差別外,沒有其他問題(他們請(qǐng)求我的web api接口有正確的響應(yīng)).

Android的,也許還能參考我的第一個(gè)參考鏈接.不過it does not work for me.

參考鏈接:

Android平臺(tái)和java平臺(tái) DES加密解密互通程序及其不能互通的原因 .

C# and Java DES Encryption value are not identical

?

版權(quán)是我的,轉(zhuǎn)載沒有通過我的同意的爬蟲都是傻逼.

?

轉(zhuǎn)載于:https://www.cnblogs.com/zeusro/p/4619873.html

總結(jié)

以上是生活随笔為你收集整理的应该怎么做一个登录功能?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。