Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲狠狠网站色噜噜,国产女主口舌奴调教视频,欧美成人a级在线视频

          整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          接口的安全設計要素:ticket,簽名,時間戳

          不點藍字,我們哪來故事?

          概述

          與前端對接的API接口,如果被第三方抓包并進行惡意篡改參數(shù),可能會導致數(shù)據(jù)泄露,甚至會被篡改數(shù)據(jù),我主要圍繞時間戳,token,簽名三個部分來保證API接口的安全性

          請求服務器超時怎么辦_請求中時間戳與服務器_請求時間參數(shù)異常是什么意思

          1.用戶成功登陸站點后,服務器會返回一個token,用戶的任何操作都必須帶了這個參數(shù),可以將這個參數(shù)直接放到header里。

          2.客戶端用需要發(fā)送的參數(shù)和token生成一個簽名sign,作為參數(shù)一起發(fā)送給服務端,服務端在用同樣的方法生成sign進行檢查是否被篡改。

          3.但這依然存在問題,可能會被進行惡意無限制訪問,這時我們需要引入一個時間戳參數(shù),如果超時即是無效的。

          4.服務端需要對token,簽名,時間戳進行驗證,只有token有效,時間戳未超時,簽名有效才能被放行。

          開放接口

          沒有進行任何限制,簡單粗暴的訪問方式,這樣的接口方式一般在開放的應用平臺,查天氣,查快遞,只要你輸入正確對應的參數(shù)調(diào)用,即可獲取到自己需要的信息,我們可以任意修改參數(shù)值。

          請求中時間戳與服務器_請求時間參數(shù)異常是什么意思_請求服務器超時怎么辦

          /*
          ?*?Description:?開放的接口
          ?*?@author?huangweicheng
          ?*?@date?2020/12/21
          */

          @RestController
          @RequestMapping("/token")
          public?class?TokenSignController?{

          ????@Autowired
          ????private?TokenSignService?tokenSignService;

          ????@RequestMapping(value?=?"openDemo",method?=?RequestMethod.GET)
          ????public?List?openDemo(int?personId){
          ????????return?tokenSignService.getPersonList(personId);
          ????}
          }

          Token認證獲取

          用戶登錄成功后,會獲取一個ticket值,接下去任何接口的訪問都需要這個參數(shù)。我們把它放置在redis內(nèi),有效期為10分鐘,在ticket即將超時,無感知續(xù)命。延長使用時間,如果用戶在一段時間內(nèi)沒進行任何操作,就需要重新登錄系統(tǒng)。擴展:

          @RequestMapping(value?=?"login",method?=?RequestMethod.POST)
          ????public?JSONObject?login(@NotNull?String?username,?@NotNull?String?password){
          ????????return?tokenSignService.login(username,password);
          ????}

          登錄操作,查看是否有這個用戶,用戶名和密碼匹配即可成功登錄。

          /**?
          ?????*?
          ?????*?Description:驗證登錄,ticket成功后放置緩存中,
          ?????*?@param
          ?????*?@author?huangweicheng
          ?????*?@date?2020/12/31???
          ????*/
          ?
          ????public?JSONObject?login(String?username,String?password){
          ????????JSONObject?result?=?new?JSONObject();
          ????????PersonEntity?personEntity?=?personDao.findByLoginName(username);
          ????????if?(personEntity?==?null?||?(personEntity?!=?null?&&?!personEntity.getPassword().equals(password))){
          ????????????result.put("success",false);
          ????????????result.put("ticket","");
          ????????????result.put("code","999");
          ????????????result.put("message","用戶名和密碼不匹配");
          ????????????return?result;
          ????????}
          ????????if?(personEntity.getLoginName().equals(username)?&&?personEntity.getPassword().equals(password)){
          ????????????String?ticket?=?UUID.randomUUID().toString();
          ????????????ticket?=?ticket.replace("-","");
          ????????????redisTemplate.opsForValue().set(ticket,personEntity.getLoginName(),10L,?TimeUnit.MINUTES);
          ????????????result.put("success",true);
          ????????????result.put("ticket",ticket);
          ????????????result.put("code",200);
          ????????????result.put("message","登錄成功");
          ????????????return?result;
          ????????}
          ????????result.put("success",false);
          ????????result.put("ticket","");
          ????????result.put("code","1000");
          ????????result.put("message","未知異常,請重試");
          ????????return?result;
          ????}

          Sign簽名

          把所有的參數(shù)拼接一起,在加入系統(tǒng)秘鑰,進行MD5計算生成一個sign簽名,防止參數(shù)被人惡意篡改,后臺按同樣的方法生成秘鑰,進行簽名對比。

          /**
          ?????*?@param?request
          ?????*?@return
          ?????*/

          ????public?static?Boolean?checkSign(HttpServletRequest?request,String?sign){
          ????????Boolean?flag=?false;
          ????????//檢查sigin是否過期
          ????????Enumeration?pNames?=??request.getParameterNames();
          ????????Map?params?=?new?HashMap();
          ????????while?(pNames.hasMoreElements())?{
          ????????????String?pName?=?(String)?pNames.nextElement();
          ????????????if("sign".equals(pName))?continue;
          ????????????String?pValue?=?(String)request.getParameter(pName);
          ????????????params.put(pName,?pValue);
          ????????}
          ????????System.out.println("現(xiàn)在的sign-->>"?+?sign);
          ????????System.out.println("驗證的sign-->>"?+?getSign(params,secretKeyOfWxh));
          ????????if(sign.equals(getSign(params,?secretKeyOfWxh))){
          ????????????flag?=?true;
          ????????}
          ????????return?flag;
          ????}

          重復訪問

          引入一個時間戳參數(shù),保證接口僅在一分鐘內(nèi)有效,需要和客戶端時間保持一致。

          請求中時間戳與服務器_請求服務器超時怎么辦_請求時間參數(shù)異常是什么意思

          public?static?long?getTimestamp(){
          ????????long?timestampLong?=?System.currentTimeMillis();

          ????????long?timestampsStr?=?timestampLong?/?1000;

          ????????return?timestampsStr;
          ????}

          需要跟當前服務器時間進行對比,如果超過一分鐘,就拒絕本次請求,節(jié)省服務器查詢數(shù)據(jù)的消耗

          攔截器

          每次請求都帶有這三個參數(shù),我們都需要進行驗證,只有在三個參數(shù)都滿足我們的要求,才允許數(shù)據(jù)返回或被操作。

          public?class?LoginInterceptor?implements?HandlerInterceptor?{

          ????@Autowired
          ????private?RedisTemplate?redisTemplate;

          ????@Override
          ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,Object?handler)?throws?IOException?{
          ????????JSONObject?jsonObject?=?new?JSONObject();
          ????????String?ticket?=?request.getParameter("ticket");
          ????????String?sign?=?request.getParameter("sign");
          ????????String?ts?=?request.getParameter("ts");
          ????????if?(StringUtils.isEmpty(ticket)?||?StringUtils.isEmpty(sign)?||?StringUtils.isEmpty(ts)){
          ????????????jsonObject.put("success",false);
          ????????????jsonObject.put("message","args?is?isEmpty");
          ????????????jsonObject.put("code","1001");
          ????????????PrintWriter?printWriter?=?response.getWriter();
          ????????????printWriter.write(jsonObject.toJSONString());
          ????????????return?false;
          ????????}
          ????????//如果redis存在ticket就認為是合法的請求
          ????????if?(redisTemplate.hasKey(ticket)){
          ????????????System.out.println(redisTemplate.opsForValue().getOperations().getExpire(ticket));
          ????????????String?values?=?(String)?redisTemplate.opsForValue().get(ticket);
          ????????????//判斷ticket是否即將過期,進行續(xù)命操作
          ????????????if?(redisTemplate.opsForValue().getOperations().getExpire(ticket)?!=?-2?&&?redisTemplate.opsForValue().getOperations().getExpire(ticket)?20){
          ????????????????redisTemplate.opsForValue().set(ticket,values,10L,?TimeUnit.MINUTES);
          ????????????}
          ????????????System.out.println(SignUtils.getTimestamp());
          ????????????//判斷是否重復訪問,存在重放攻擊的時間窗口期
          ????????????if?(SignUtils.getTimestamp()?-?Long.valueOf(ts)?>?600){
          ????????????????jsonObject.put("success",false);
          ????????????????jsonObject.put("message","Overtime?to?connect?to?server");
          ????????????????jsonObject.put("code","1002");
          ????????????????PrintWriter?printWriter?=?response.getWriter();
          ????????????????printWriter.write(jsonObject.toJSONString());
          ????????????????return?false;
          ????????????}
          ????????????//驗證簽名
          ????????????if?(!SignUtils.checkSign(request,sign)){
          ????????????????jsonObject.put("success",false);
          ????????????????jsonObject.put("message","sign?is?invalid");
          ????????????????jsonObject.put("code","1003");
          ????????????????PrintWriter?printWriter?=?response.getWriter();
          ????????????????printWriter.write(jsonObject.toJSONString());
          ????????????????return?false;
          ????????????}
          ????????????return?true;
          ????????}else?{
          ????????????jsonObject.put("success",false);
          ????????????jsonObject.put("message","ticket?is?invalid,Relogin.");
          ????????????jsonObject.put("code","1004");
          ????????????PrintWriter?printWriter?=?response.getWriter();
          ????????????printWriter.write(jsonObject.toJSONString());
          ????????}
          ????????return?false;
          ????}
          }

          訪問

          先登錄系統(tǒng),獲取合法的ticket

          請求中時間戳與服務器_請求時間參數(shù)異常是什么意思_請求服務器超時怎么辦

          生成一個合法的sign驗證,獲取測試ts,訪問,即可正常訪問。還可以將參數(shù)加密,將http換成https,就不一 一展開了。

          請求中時間戳與服務器_請求時間參數(shù)異常是什么意思_請求服務器超時怎么辦

          demo代碼

          往期推薦

          多點控制單元 選擇轉(zhuǎn)發(fā)單元 tutorial 1 documentation

          選擇性轉(zhuǎn)發(fā)單元 SFU( Unit)在各個端點之間交換音頻和視頻流。 每個接收器方可以選擇它所要接收的流和層(空間/時間上)。 與 MCU(多點控制單元)相比,這種設計可以帶來更好的性能、更高的吞吐量和更少的延遲。 鑒于它不做轉(zhuǎn)碼或合成媒體,所以它具有高度可擴展性,并且需要的資源少得多。

          由于各個端點分別獲取其他端點的媒體,因此它們可以具有個性化的布局,并選擇自己所要呈現(xiàn)的媒體流,以及決定如何顯示它們。

          SFU 可以看作一個多媒體流的路由器,實踐中可以應用發(fā)布訂閱模式( publish/ pattern)

          libuv

          refer to

          room-<unique room ID>: {
                  description = This is my awesome room
                  is_private = true|false (private rooms don't appear when you do a 'list' request, default=false)
                  secret = <optional password needed for manipulating (e.g. destroying) the room>
                  pin = <optional password needed for joining the room>
                  require_pvtid = true|false (whether subscriptions are required to provide a valid private_id
                                          to associate with a publisher, default=false)
                  publishers = <max number of concurrent senders> (e.g., 6 for a video
                                          conference or 1 for a webinar, default=3)
                  bitrate = <max video bitrate for senders> (e.g., 128000)
                  bitrate_cap = <true|false, whether the above cap should act as a limit to dynamic bitrate changes by publishers, default=false>,
                  fir_freq = <send a FIR to publishers every fir_freq seconds> (0=disable)
          

          單元轉(zhuǎn)發(fā)控制點選擇方法_城區(qū)控制所屬單元_多點控制單元 選擇轉(zhuǎn)發(fā)單元

          audiocodec = opus|g722|pcmu|pcma|isac32|isac16 (audio codec to force on publishers, default=opus can be a comma separated list in order of preference, e.g., opus,pcmu) videocodec = vp8|vp9|h264|av1|h265 (video codec to force on publishers, default=vp8 can be a comma separated list in order of preference, e.g., vp9,vp8,h264) vp9_profile = VP9-specific profile to prefer (e.g., "2" for "profile-id=2") h264_profile = H.264-specific profile to prefer (e.g., "42e01f" for "profile-level-id=42e01f") opus_fec = true|false (whether inband FEC must be negotiated; only works for Opus, default=false) video_svc = true|false (whether SVC support must be enabled; only works for VP9, default=false) audiolevel_ext = true|false (whether the ssrc-audio-level RTP extension must be negotiated/used or not for new publishers, default=true) audiolevel_event = true|false (whether to emit event to other users or not, default=false) audio_active_packets = 100 (number of packets with audio level, default=100, 2 seconds) audio_level_average = 25 (average value of audio level, 127=muted, 0='too loud', default=25) videoorient_ext = true|false (whether the video-orientation RTP extension must be negotiated/used or not for new publishers, default=true) playoutdelay_ext = true|false (whether the playout-delay RTP extension must be negotiated/used or not for new publishers, default=true) transport_wide_cc_ext = true|false (whether the transport wide CC RTP extension must be

          城區(qū)控制所屬單元_多點控制單元 選擇轉(zhuǎn)發(fā)單元_單元轉(zhuǎn)發(fā)控制點選擇方法

          negotiated/used or not for new publishers, default=true) record = true|false (whether this room should be recorded, default=false) rec_dir = <folder where recordings should be stored, when enabled> lock_record = true|false (whether recording can only be started/stopped if the secret is provided, or using the global enable_recording request, default=false) notify_joining = true|false (optional, whether to notify all participants when a new participant joins the room. The Videoroom plugin by design only notifies new feeds (publishers), and enabling this may result extra notification traffic. This flag is particularly useful when enabled with require_pvtid for admin to manage listening only participants. default=false) require_e2ee = true|false (whether all participants are required to publish and subscribe using end-to-end media encryption, e.g., via Insertable Streams; default=false) }

          ? 2021 ~ 2023, Walter Fan, Commons -- 4.0 License.

          Built with Sphinx using by Read the Docs.


          主站蜘蛛池模板: 无码人妻精品一区二区三区久久| 日本一区二区三区免费高清| 亚洲一本一道一区二区三区| 少妇无码AV无码一区| 精品永久久福利一区二区| 精品91一区二区三区| 亚洲国产系列一区二区三区 | 视频一区视频二区在线观看| 亚洲AV无码一区二区三区DV| 久久国产精品免费一区| 日本一区二区三区在线视频观看免费 | 性色av闺蜜一区二区三区| 麻豆天美国产一区在线播放| 精品国产一区二区三区久久 | 不卡一区二区在线| 日韩经典精品无码一区| 精品一区狼人国产在线| 国产一区二区草草影院| 亚洲熟妇无码一区二区三区| 精品国产a∨无码一区二区三区 | 国产伦精品一区二区三区四区| 一色一伦一区二区三区| 亚洲国产欧美日韩精品一区二区三区| 久久se精品一区精品二区| 国产精品视频一区二区噜噜| 国产高清视频一区三区| 国产高清视频一区三区| 久久久老熟女一区二区三区| 精品国产乱码一区二区三区| 亚洲国产精品一区二区三区在线观看| 久久无码人妻一区二区三区午夜| 久久精品一区二区三区AV| 国内精品一区二区三区东京| 无码人妻精品一区二区三区久久久 | 精品一区二区三区四区在线 | 美女福利视频一区二区| 日韩国产一区二区| 高清国产AV一区二区三区| 一区二区三区精品| 国产精品一区视频| 搜日本一区二区三区免费高清视频 |