当前位置: 首页 > news >正文

网站产品后台界面怎么做电商软件app开发

网站产品后台界面怎么做,电商软件app开发,湘潭网站建设哪些公司,全国统一证书查询官网我们有HTTPS#xff0c;还需要什么#xff1f; 当您谈论基于REST的API的安全性时#xff0c;人们通常会指向HTTPS。 借助HTTPS#xff0c;您可以使用每个人都熟悉的方法轻松保护您的服务免遭窥视。 但是#xff0c;当您需要更高级别的安全性或HTTPS不可用时#xff0c;您… 我们有HTTPS还需要什么 当您谈论基于REST的API的安全性时人们通常会指向HTTPS。 借助HTTPS您可以使用每个人都熟悉的方法轻松保护您的服务免遭窥视。 但是当您需要更高级别的安全性或HTTPS不可用时您需要替代方法。 例如您可能需要跟踪每个客户对API的使用情况或者需要确切地知道谁在进行所有这些调用。 您可以将HTTPS与客户端身份验证一起使用但这将需要设置完整的PKI基础结构以及一种安全的方式来标识您的客户并交换私钥。 与基于SOAP的WS-Security服务相比我们没有可用于REST的标准。 解决此问题的常用方法MicrosoftAmazonGoogle和Yahoo采用此方法是通过基于客户端与服务之间的共享机密对消息进行签名。 请注意使用这种方法我们仅对数据进行签名而不对数据进行加密。 在这种情况下我们所讨论的签名通常称为基于哈希的消息认证代码简称HMAC。 使用HMAC我们根据已交换的密钥为请求创建消息认证码MAC。 在本文中我将向您展示如何为基于Play 2.0的REST服务实现此算法。 如果您使用其他技术则步骤将几乎相同。 HMAC方案 对于客户端我将仅使用基于HTTPClient的简单应用程序。 要实现这一点我们必须采取以下步骤 首先我们需要与外部客户端交换共享机密。 通常这是由API提供程序使用电子邮件发送给客户端的或者提供程序具有一个您可以在其中查找共享密钥的网站。 请注意此机密仅在您和服务之间共享每个客户端将具有不同的共享机密。 这不是像公用密钥那样共享的东西 为了确保客户端和服务在同一内容上计算签名我们需要对要签名的请求进行规范化。 如果我们不这样做则服务器可能会以与客户端不同的方式解释空格并得出签名无效的结论。 基于此规范化消息客户端使用共享机密创建HMAC值。 现在客户端已准备好将请求发送到服务。 他将HMAC值添加到标头中还将一些内容标识为用户。 例如用户名或其他公共值。 当服务收到请求时它将从标头中提取用户名和HMAC值。 根据用户名服务知道应该使用哪个共享密钥对消息进行签名。 例如该服务将从某处的数据存储中检索此信息。 现在服务以与客户端相同的方式对请求进行规范化并为其自身计算HMAC值。 如果来自客户端的HMAC与从服务器计算出的HMAC相匹配则您将知道消息的完整性得到保证并且客户端就是他所说的身份。 如果提供了错误的用户名或者使用了错误的机密来计算标题则HMAC值将不匹配。 要实现HMAC我们需要做什么 在以下部分中我们将研究以下主题。 确定用于输入的字段。 创建可以计算此HMAC的客户端代码并添加相应的标头 创建基于Play 2.0的拦截器来检查HMAC标头 确定输入字段 我们要做的第一件事是确定HMAC计算的输入。 下表描述了我们将包括的元素 领域 描述 HTTP方法 使用REST我们执行的HTTP方法定义了服务器端的行为。 对特定URL的删除与对该URL的GET处理不同。 内容MD5 此HTTP标头是标准HTTP标头。 这是请求正文的MD5哈希。 如果我们将此标头包含在HMAC代码生成中则会获得一个HMAC值该值会随着请求正文的更改而更改。 Content-Type标头 进行REST调用时Content-Type标头是重要的标头。 服务器可以根据媒体类型对请求做出不同的响应因此应将其包含在HMAC中。 日期标题 我们还包括创建请求以计算HMAC的日期。 在服务器端我们可以确保日期在传输中没有更改。 除此之外我们可以在服务器上添加消息过期功能。 路径 由于URI标识REST中的资源因此调用的URL的路径部分也用于HMAC计算。 我们将包括的几乎是来自请求的以下信息 PUT /example/resource/1 Content-Md5: ufFg2jkrCZgzDcznsdwLg Content-Type: text/plain; charsetUTF-8 Date: Tue, 26 Apr 2011 19:59:03 CEST 可用于创建HMAC签名的客户端代码 在下面您可以看到我们用来调用受HMAC保护的服务的客户端代码。 这只是一个基于HTTPClient的快速客户端我们可以使用它来测试我们的服务。 public class HMACClient {private final static String DATE_FORMAT EEE, d MMM yyyy HH:mm:ss z;private final static String HMAC_SHA1_ALGORITHM HmacSHA1;private final static String SECRET secretsecret;private final static String USERNAME jos;private static final Logger LOG LoggerFactory.getLogger(HMACClient.class);public static void main(String[] args) throws HttpException, IOException, NoSuchAlgorithmException {HMACClient client new HMACClient();client.makeHTTPCallUsingHMAC(USERNAME);}public void makeHTTPCallUsingHMAC(String username) throws HttpException, IOException, NoSuchAlgorithmException {String contentToEncode {\comment\ : {\message\:\blaat\ , \from\:\blaat\ , \commentFor\:123}};String contentType application/vnd.geo.commentjson;//String contentType text/plain;String currentDate new SimpleDateFormat(DATE_FORMAT).format(new Date());HttpPost post new HttpPost(http://localhost:9000/resources/rest/geo/comment);StringEntity data new StringEntity(contentToEncode,contentType,UTF-8);post.setEntity(data);String verb post.getMethod();String contentMd5 calculateMD5(contentToEncode);String toSign verb \n contentMd5 \n data.getContentType().getValue() \n currentDate \n post.getURI().getPath();String hmac calculateHMAC(SECRET, toSign);post.addHeader(hmac, username : hmac);post.addHeader(Date, currentDate);post.addHeader(Content-Md5, contentMd5);HttpClient client new DefaultHttpClient();HttpResponse response client.execute(post);System.out.println(client response: response.getStatusLine().getStatusCode());}private String calculateHMAC(String secret, String data) {try {SecretKeySpec signingKey new SecretKeySpec(secret.getBytes(), HMAC_SHA1_ALGORITHM);Mac mac Mac.getInstance(HMAC_SHA1_ALGORITHM);mac.init(signingKey);byte[] rawHmac mac.doFinal(data.getBytes());String result new String(Base64.encodeBase64(rawHmac));return result;} catch (GeneralSecurityException e) {LOG.warn(Unexpected error while creating hash: e.getMessage(), e);throw new IllegalArgumentException();}}private String calculateMD5(String contentToEncode) throws NoSuchAlgorithmException {MessageDigest digest MessageDigest.getInstance(MD5);digest.update(contentToEncode.getBytes());String result new String(Base64.encodeBase64(digest.digest()));return result;} } 然后使用HMAC算法基于共享机密创建签名。 private String calculateHMAC(String secret, String data) {try {SecretKeySpec signingKey new SecretKeySpec(secret.getBytes(), HMAC_SHA1_ALGORITHM);Mac mac Mac.getInstance(HMAC_SHA1_ALGORITHM);mac.init(signingKey);byte[] rawHmac mac.doFinal(data.getBytes());String result new String(Base64.encodeBase64(rawHmac));return result;} catch (GeneralSecurityException e) {LOG.warn(Unexpected error while creating hash: e.getMessage(), e);throw new IllegalArgumentException();}} 计算完HMAC值后我们需要将其发送到服务器。 为此我们提供了一个自定义标头 post.addHeader(hmac, username : hmac); 如您所见我们还添加了用户名。 服务器需要使用它来确定在服务器端使用哪个密钥来计算HMAC值。 现在当我们运行此代码时将执行一个简单的POST操作将以下请求发送到服务器 POST /resources/rest/geo/comment HTTP/1.1[\r][\n] hmac: jos:9tn0CLfxXFbzPmbYwq/KYuUSUI[\r][\n] Date: Mon, 26 Mar 2012 21:34:33 CEST[\r][\n] Content-Md5: r52FDQv6V2GHN4neZBvXLQ[\r][\n] Content-Length: 69[\r][\n] Content-Type: application/vnd.geo.commentjson; charsetUTF-8[\r][\n] Host: localhost:9000[\r][\n] Connection: Keep-Alive[\r][\n] User-Agent: Apache-HttpClient/4.1.3 (java 1.5)[\r][\n] [\r][\n] {comment : {message:blaat , from:blaat , commentFor:123}} 在Scala中实现/播放 到目前为止我们已经看到客户需要做什么才能为我们提供正确的标题。 服务提供商通常会提供多种语言的特定库用于处理消息签名的详细信息。 但是正如您所看到的手工完成并不困难。 现在让我们看一下服务器端在此我们将scala与Play 2.0框架一起使用以检查提供的标头是否包含正确的信息。 有关设置正确的Scala环境以测试此代码的更多信息请参阅我以前在scala上的帖子 http://www.smartjava.org/content/play-20-akka-rest-json-and-dependencies 。 首先要做的是设置正确的路由以支持此POST操作。 我们在conf / routes文件中执行此操作 POST /resources/rest/geo/comment controllers.Application.addComment 这是基本的Play功能。 对/ resource / rest / geo / comment URL的所有POST调用都将传递到指定的控制器。 让我们看一下该操作的样子 def addComment() Authenticated {(user, request) {// convert the supplied json to a comment objectval comment Json.parse(request.body.asInstanceOf[String]).as[Comment]// pass the comment object to a service for processingcommentService.storeComment(comment)println(Json.toJson(comment))Status(201)}} 现在它变得更加复杂了。 如您在上面的清单中所见我们定义了一个addComment操作。 但是与其直接定义这样的动作不如 def processGetAllRequest() Action {val result service.processGetAllRequest;Ok(result).as(application/json);} 我们改为这样定义它 def addComment() Authenticated {(user, request) { 我们在这里所做的是创建一个复合动作http://www.playframework.org/documentation/2.0/ScalaActionsComposition 。 因为Scala是一种功能语言所以我们可以轻松地做到这一点。 您在此处看到的“已认证”引用只是对简单函数的简单引用该函数以另一个函数作为参数。 在“已验证”功能中我们将检查HMAC签名。 您可以将其读为使用批注但现在无需任何特殊构造。 因此我们的HMAC检查是什么样的。 import play.api.mvc.Action import play.api.Logger import play.api.mvc.RequestHeader import play.api.mvc.Request import play.api.mvc.AnyContent import play.api.mvc.Result import controllers.Application._ import java.security.MessageDigest import javax.crypto.spec.SecretKeySpec import javax.crypto.Mac import org.apache.commons.codec.binary.Base64 import play.api.mvc.RawBuffer import play.api.mvc.Codec/*** Obejct contains security actions that can be applied to a specific action called from* a controller.*/ object SecurityActions {val HMAC_HEADER hmacval CONTENT_TYPE_HEADER content-typeval DATE_HEADER Dateval MD5 MD5val HMACSHA1 HmacSHA1/*** Function authenticated is defined as a function that takes as parameter* a function. This function takes as argumens a user and a request. The authenticated* function itself, returns a result.** This Authenticated function will extract information from the request and calculate* an HMAC value.***/def Authenticated(f: (User, Request[Any]) Result) {// we parse this as tolerant text, since our content type// is application/vnd.geo.commentjson, which isnt picked// up by the default body parsers. Alternative would be// to parse the RawBuffer manuallyAction(parse.tolerantText) {request {// get the header were working withval sendHmac request.headers.get(HMAC_HEADER);// Check whether weve recevied an hmac headersendHmac match {// if weve got a value that looks like our header case Some(x) if x.contains(:) x.split(:).length 2 {// first part is username, second part is hashval headerParts x.split(:);val userInfo User.find(headerParts(0))// Retrieve all the headers were going to use, we parse the complete // content-type header, since our client also does thisval input List(request.method,calculateMD5(request.body),request.headers.get(CONTENT_TYPE_HEADER),request.headers.get(DATE_HEADER),request.path)// create the string that well have to signval toSign input.map(a {a match {case None case a: Option[Any] a.asInstanceOf[Option[Any]].getcase _ a}}).mkString(\n)// use the input to calculate the hmacval calculatedHMAC calculateHMAC(userInfo.secret, toSign)// if the supplied value and the received values are equal// return the response from the delegate action, else return// unauthorizedif (calculatedHMAC headerParts(1)) {f(userinfo, request)} else {Unauthorized}}// All the other possibilities return to 401 case _ Unauthorized}}}}/*** Calculate the MD5 hash for the specified content*/private def calculateMD5(content: String): String {val digest MessageDigest.getInstance(MD5)digest.update(content.getBytes())new String(Base64.encodeBase64(digest.digest()))}/*** Calculate the HMAC for the specified data and the supplied secret*/private def calculateHMAC(secret: String, toEncode: String): String {val signingKey new SecretKeySpec(secret.getBytes(), HMACSHA1)val mac Mac.getInstance(HMACSHA1)mac.init(signingKey)val rawHmac mac.doFinal(toEncode.getBytes())new String(Base64.encodeBase64(rawHmac))} } 那是很多代码但是其中大多数将很容易理解。 “ calculateHMAC”和“ calculateMD5”方法只是围绕Java功能的基本scala包装器。 该类内的文档应该足以了解正在发生的事情。 但是我确实想在这段代码中突出几个有趣的概念。 首先是方法签名 def Authenticated(f: (User, Request[Any]) Result) { 这意味着Authenticated方法本身将另一个方法或函数如果要调用该方法作为参数。 如果回头看我们的路线目标您会发现我们只是这样做 def addComment() Authenticated {(user, request) ... 现在当调用此“已认证”方法时会发生什么 我们要做的第一件事是检查HMAC标头是否存在并且格式正确 val sendHmac request.headers.get(HMAC_HEADER);sendHmac match {// if weve got a value that looks like our header case Some(x) if x.contains(:) x.split(:).length 2 {...}// All the other possibilities return to 401 case _ Unauthorized 我们通过对HMAC标头使用匹配来实现。 如果它包含正确格式的值则我们将处理标头并以与客户端相同的方式计算HMAC值。 如果不是则返回401。如果HMAC值正确则使用以下代码将其委托给提供的函数 if (calculatedHMAC headerParts(1)) {f(userInfo, request)} else {Unauthorized} 就是这样。 使用此代码您可以轻松地使用HMAC来检查邮件在传输过程中是否已更改以及您的客户是否真正为您所知。 如您所见非常简单。 只是Play 2.0中有关JSON使用情况的一小部分便条。 如果您查看操作代码则可以看到我使用了标准的JSON功能 def addComment() Authenticated {(user, request) {// convert the supplied json to a comment objectval comment Json.parse(request.body.asInstanceOf[String]).as[Comment]// pass the comment object to a service for processingcommentService.storeComment(comment)println(Json.toJson(comment))Status(201)}} 首先我们使用json.parse将接收到的JSON解析为comment类然后存储注释并将命令对象转换回字符串值。 不是最有用的代码但它很好地演示了Play 2.0提供的一些JSON功能。 为了从JSON转换为对象并再次返回使用了一种称为“隐式转换”的方法。 我不会在细节上过多介绍但是可以在这里找到很好的解释 http : //www.codecommit.com/blog/ruby/implicit-conversions-more-powerful-t… 。 这里发生的是JSON.parse和Json.toJson方法在Comment类上寻找特定的方法。 如果无法在此处找到它它将在其范围内查找特定的操作。 要查看此方法如何用于JSON解析让我们看一下Comment类及其配套对象 import play.api.libs.json.Format import play.api.libs.json.JsValue import play.api.libs.json.JsObject import play.api.libs.json.JsString import play.api.libs.json.JsNumber import play.api.libs.json.JsArrayobject Comment {implicit object CommentFormat extends Format[Comment] {def reads(json: JsValue): Comment {val root (json \ comment)Comment((root \ message).as[String],(root \ from).as[String],(root \ commentFor).as[Long])}def writes(comment: Comment): JsValue {JsObject(List(comment -JsObject(Seq(message - JsString(comment.message),from - JsString(comment.message),commentFor - JsNumber(comment.commentFor)))))}}}case class Comment(message: String, from: String, commentFor: Long) {} 您在此处看到的是在伴随对象中我们创建了一个新的“格式”对象。 现在与“ Comment”类一起使用时JSON操作将使用此对象中的“读取”和“写入”操作来进行JSON转换。 非常强大的功能尽管有些神奇-)有关在此示例中使用的Scala / Play环境的更多信息请参见我以前的文章 http://www.smartjava.org/content/play-20-akka-rest-json-and-dependencies http://www.smartjava.org/content/using-querulous-scala-postgresql 参考来自Smart Java博客的JCG合作伙伴 Jos Dirksen 使用HMACPlay 2.0保护REST服务 。 翻译自: https://www.javacodegeeks.com/2012/04/dzoneprotect-rest-service-using-hmac.html
http://www.yutouwan.com/news/316963/

相关文章:

  • 如何建设和优化网站网站建设流程报告
  • 中国最好网站建设公司信用信息公示网官网
  • 什么是网站设计与建设建设虚拟币交易网站
  • 西安网站搭建公司公司网站标题优化
  • 企业管理网站厦门seo外包平台
  • 济南做网站优化哪家好wordpress.or
  • 山东省品牌建设促进会网站注册城乡规划师含金量
  • 做创业网站赚钱可以做外链的网站有哪些
  • 天津魔方网站建设建设工程施工证哪个网站查询
  • 怎样向网站上传照片电商网站话费充值怎么做
  • 案例上海网站百度开户怎么开
  • 中国纪检监察网站首页wordpress百度熊掌
  • 国外网站策划网站 微信开发
  • 企业如何做网站收款网页制作培训苏州
  • 杭州高瑞网站建设企业年报网上申报系统
  • 网站建设万禾西安关键词快速排名
  • 企业网站的作用想做个网站 在哪买域名和空间
  • 网站建设学习 服务器如何免费建购物网站
  • DW网站建设出现哪些问题建网站那种服务器好
  • 网站设计的意义做网站可以做什么
  • 网站建设制作公司景区网站模板
  • 大型门户网站建设效果好吗局域网内做网站
  • 网站流量查询站长之家企业网站推广的形式有哪些
  • 建微信网站南通做网站的公司
  • 广州网站建设培训班中文域名网站有哪些
  • 怎么增加网站的权重创办一个app需要多少钱
  • 北京seo网站诊断黄页引流推广链接
  • 网站数据库配置如何在局域网建立网站
  • 优秀企业网站躺平设计家官网
  • 蜘蛛云建站网站石家庄住房和城乡建设部网站