多系统间接口调用安全鉴权(App-Key、Timestamp、App-Sign)


多系统间接口调用安全鉴权(App-Key、Timestamp、App-Sign)


将secretKey发给调用系统,以备调用系统调用门户系统接口鉴权使用
 调用系统的请求头中有App-Key(调用系统名称)、Timestamp(时间戳)、App-Sign
 appSign生成规则:DigestUtils.md5Hex(appKey + timestamp + secretKey)
在收到请求后,解析请求头字段,并在本地生成appSign,
 规则:DigestUtils.md5Hex(appKey + timestamp + secretKey)
  然后比较两者是否相同,相同则放行,不同则截断

以下是鉴权工具类分享:


import cn.hutool.core.collection.CollectionUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 将secretKey发给调用系统,以备调用系统调用门户系统接口鉴权使用
 * 调用系统的请求头中有App-Key(调用系统名称)、Timestamp(时间戳)、App-Sign
 * appSign生成规则:DigestUtils.md5Hex(appKey + timestamp + secretKey)
 *
 * 在收到请求后,解析请求头字段,并在本地生成appSign,
 * 规则:DigestUtils.md5Hex(appKey + timestamp + secretKey)
 * 然后比较两者是否相同,相同则放行,不同则截断
 * @author yangqing 
 * @title: DigestUtils
 * @projectName
 * @description: 鉴权工具类
 * @date 2020/7/30 14:35
 */
public class DigestSignUtils {
    //add by yangqing 2020-07-30   start
    private static final Logger LOGGER = LoggerFactory.getLogger(DigestSignUtils.class);
    //add by yangqing 2020-07-30   end

    public static final String Timestamp = "Timestamp";

    public static final String App_Key = "App-Key";

    public static final String App_Sign = "App-Sign";

    public static Boolean isAuth(HttpServletRequest request){
        Map<String, String> headerMap = getHeadersInfo(request);
        LOGGER.info("header param is {}",headerMap);
        if(CollectionUtil.isEmpty(headerMap)) {
            return false;
        }

        //对方系统传参
        String timeStamp = MapUtils.getString(headerMap,Timestamp);
        String appKey = MapUtils.getString(headerMap,App_Key);
        String appSign = MapUtils.getString(headerMap,App_Sign);
        if(StringUtils.isEmpty(timeStamp) || StringUtils.isEmpty(appKey) || StringUtils.isEmpty(appSign)) {
            return false;
        }

        //appkey+timestamp+本地secretkey生成sign
        //从数据库中根据appKey 获取systemSecretKey  暂时写死  待写业务逻辑时修改回来
        String systemSecretKey = "0266a29fa1fa4e02a1e960f25e4ae87e";
        String realAppSign = DigestUtils.md5Hex(appKey + timeStamp + systemSecretKey);
        LOGGER.info("realAppSign is {},appSign is {}",realAppSign,appSign);
        //比对成功,则放行
        if(StringUtils.equals(appSign, realAppSign)) {
            return true;
        }
        return false;
    }

    /**
     * 获取请求头字段key-value
     *@Author yangqing 
     *@Date  2020/7/30 10:47
     *@param request
     *@return java.util.Map<java.lang.String,java.lang.String>
     *@throws
     */
    private static Map<String, String> getHeadersInfo(HttpServletRequest request) {
        //add by yangqing --获取请求头字段key-value 20200730 start
        LOGGER.info("{} : 获取请求头字段key-value  request:", request);
        Map<String, String> map = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        //性能考虑:使用Enumeration
        /**
         *     Enumeration keys costs 6 milliseconds
         *   Enumeration elements costs 5 milliseconds
         *   Iterator keySet costs 10 milliseconds
         *   Iterator entrySet costs 10 milliseconds
         */
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        LOGGER.info("{} : 获取请求头字段key-value  获取请求头参数:", map);
        return map;
        //add by yangqing --获取请求头字段key-value 20200730 end
    }
}

以下是很挫很挫的main函数测试:


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.*;

public class DigestSignTest {
    public static void main(String[] args) {
        HttpServletRequest request = new HttpServletRequest() {
            public String getAuthType() {
                return null;
            }

            public Cookie[] getCookies() {
                return new Cookie[0];
            }

            public long getDateHeader(String s) {
                return 0;
            }

            public String getHeader(String s) {
                Map<String, String> v = new HashMap<String, String>();
                v.put("Timestamp", "12345678912");
                v.put("App-Key", "superMan");
                v.put("App-Sign", "00d777ecfe05b9bd2a4d616f58b44556");
                return v.get(s);
            }

            public Enumeration<String> getHeaders(String s) {
                Vector v = new Vector();
                v.addElement("Timestamp");
                v.addElement("App-Key");
                v.addElement("App-Sign");
                Enumeration e = v.elements();
                return e;
            }

            public Enumeration<String> getHeaderNames() {
                Vector v = new Vector();
                v.addElement("Timestamp");
                v.addElement("App-Key");
                v.addElement("App-Sign");
                Enumeration e = v.elements();
                return e;
            }

            public int getIntHeader(String s) {
                return 0;
            }

            public String getMethod() {
                return null;
            }

            public String getPathInfo() {
                return null;
            }

            public String getPathTranslated() {
                return null;
            }

            public String getContextPath() {
                return null;
            }

            public String getQueryString() {
                return null;
            }

            public String getRemoteUser() {
                return null;
            }

            public boolean isUserInRole(String s) {
                return false;
            }

            public Principal getUserPrincipal() {
                return null;
            }

            public String getRequestedSessionId() {
                return null;
            }

            public String getRequestURI() {
                return null;
            }

            public StringBuffer getRequestURL() {
                return null;
            }

            public String getServletPath() {
                return null;
            }

            public HttpSession getSession(boolean b) {
                return null;
            }

            public HttpSession getSession() {
                return null;
            }

            public String changeSessionId() {
                return null;
            }

            public boolean isRequestedSessionIdValid() {
                return false;
            }

            public boolean isRequestedSessionIdFromCookie() {
                return false;
            }

            public boolean isRequestedSessionIdFromURL() {
                return false;
            }

            public boolean isRequestedSessionIdFromUrl() {
                return false;
            }

            public boolean authenticate(HttpServletResponse httpServletResponse) throws IOException, ServletException {
                return false;
            }

            public void login(String s, String s1) throws ServletException {

            }

            public void logout() throws ServletException {

            }

            public Collection<Part> getParts() throws IOException, ServletException {
                return null;
            }

            public Part getPart(String s) throws IOException, ServletException {
                return null;
            }

            public <T extends HttpUpgradeHandler> T upgrade(Class<T> aClass) throws IOException, ServletException {
                return null;
            }

            public Object getAttribute(String s) {
                return null;
            }

            public Enumeration<String> getAttributeNames() {
                return null;
            }

            public String getCharacterEncoding() {
                return null;
            }

            public void setCharacterEncoding(String s) throws UnsupportedEncodingException {

            }

            public int getContentLength() {
                return 0;
            }

            public long getContentLengthLong() {
                return 0;
            }

            public String getContentType() {
                return null;
            }

            public ServletInputStream getInputStream() throws IOException {
                return null;
            }

            public String getParameter(String s) {
                return null;
            }

            public Enumeration<String> getParameterNames() {
                return null;
            }

            public String[] getParameterValues(String s) {
                return new String[0];
            }

            public Map<String, String[]> getParameterMap() {
                return null;
            }

            public String getProtocol() {
                return null;
            }

            public String getScheme() {
                return null;
            }

            public String getServerName() {
                return null;
            }

            public int getServerPort() {
                return 0;
            }

            public BufferedReader getReader() throws IOException {
                return null;
            }

            public String getRemoteAddr() {
                return null;
            }

            public String getRemoteHost() {
                return null;
            }

            public void setAttribute(String s, Object o) {

            }

            public void removeAttribute(String s) {

            }

            public Locale getLocale() {
                return null;
            }

            public Enumeration<Locale> getLocales() {
                return null;
            }

            public boolean isSecure() {
                return false;
            }

            public RequestDispatcher getRequestDispatcher(String s) {
                return null;
            }

            public String getRealPath(String s) {
                return null;
            }

            public int getRemotePort() {
                return 0;
            }

            public String getLocalName() {
                return null;
            }

            public String getLocalAddr() {
                return null;
            }

            public int getLocalPort() {
                return 0;
            }

            public ServletContext getServletContext() {
                return null;
            }

            public AsyncContext startAsync() throws IllegalStateException {
                return null;
            }

            public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
                return null;
            }

            public boolean isAsyncStarted() {
                return false;
            }

            public boolean isAsyncSupported() {
                return false;
            }

            public AsyncContext getAsyncContext() {
                return null;
            }

            public DispatcherType getDispatcherType() {
                return null;
            }
        };
        Boolean bl = DigestSignUtils.isAuth(request);
        System.out.println("bl:" + bl);
    }
}

谢谢大家的支持,希望对大佬们有帮助!


  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 uniapp调用微信支付接口,需要先在微信公众平台申请开通微信支付,并获取到相关的 appid、mch_id、key 等信息。然后按照以下步骤进行操作: 1. 引入 wxpay.js 在 uniapp 项目中的 static 目录下新建 wxpay.js 文件,将以下代码复制进去: ``` export default { wxpay: function (orderId, successCallback, errorCallback) { uni.request({ url: 'http://your.domain.com/pay.php', // 将此 URL 替换为你自己的后端支付接口 URL method: 'POST', data: { orderId: orderId }, success: function (res) { var payargs = res.data.payargs; wx.requestPayment({ 'timeStamp': payargs.timeStamp, 'nonceStr': payargs.nonceStr, 'package': payargs.package, 'signType': payargs.signType, 'paySign': payargs.paySign, 'success': function (res) { successCallback(res); }, 'fail': function (res) { errorCallback(res); } }) }, fail: function (res) { errorCallback(res); } }) } } ``` 2. 调用 wxpay.js 在需要调用微信支付的页面中,引入 wxpay.js,并在合适的时机调用 wxpay 方法,例如: ``` import wxpay from '@/static/wxpay.js'; wxpay.wxpay(orderId, function (res) { // 支付成功回调函数 }, function (res) { // 支付失败回调函数 }); ``` 其中,orderId 参数为你的订单号,successCallback 和 errorCallback 分别为支付成功和支付失败的回调函数。 3. 后端支付接口 在后端编写支付接口,将订单信息传递给微信支付接口,并返回支付所需的参数,例如: ``` <?php // 订单信息 $order = array( 'appid' => 'your_appid', 'mch_id' => 'your_mch_id', 'nonce_str' => uniqid(), 'body' => '商品描述', 'out_trade_no' => $_POST['orderId'], 'total_fee' => '订单总金额,单位为分', 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], 'notify_url' => '支付结果通知地址', 'trade_type' => 'APP' ); // 生成签名 ksort($order); $str = ''; foreach ($order as $key => $value) { $str .= $key . '=' . $value . '&'; } $str .= 'key=your_key'; $order['sign'] = strtoupper(md5($str)); // 调用微信支付接口 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $xml = '<xml>'; foreach ($order as $key => $value) { $xml .= '<' . $key . '>' . $value . '</' . $key . '>'; } $xml .= '</xml>'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); $data = curl_exec($ch); curl_close($ch); // 解析返回结果 $xml = simplexml_load_string($data); if ($xml->return_code == 'SUCCESS' && $xml->result_code == 'SUCCESS') { $payargs = array( 'appId' => 'your_appid', 'timeStamp' => strval(time()), 'nonceStr' => uniqid(), 'package' => 'prepay_id=' . $xml->prepay_id, 'signType' => 'MD5' ); ksort($payargs); $str = ''; foreach ($payargs as $key => $value) { $str .= $key . '=' . $value . '&'; } $str .= 'key=your_key'; $payargs['paySign'] = strtoupper(md5($str)); echo json_encode(array('payargs' => $payargs)); } else { echo json_encode(array('error' => '支付失败')); } ``` 注意将其中的 your_appid、your_mch_id、your_key 等参数替换为自己申请的信息。同时,notify_url 参数需要设置为支付结果通知的后端接口地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值