iOS 中会话认证机制共有四种,大体分为两种类型:
枚举类如下:

单向认证
指客户端验证服务端的身份,服务端不验证客户端身份;
双向认证
指客户端验证服务端身份,服务端也认证客户端身份,未通过认证的客户端在握手阶段直接断开连接,禁止访问服务器;
NTLM 和 Kerberos
用于早期的 Windows 中,不做深入研究;
说明:
HTTPS 通信中一般都是单向认证,这样可以保证数据的加密传输,也能够防止没有证书的钓鱼网站。而双向认证一般用于企业来禁止接口被第三方调用和解析。iOS 中的 NSURLSession 的默认实现、AFN 的默认实现都是单向认证,此时代理方法只会受到一种类型的回调,即: NSURLAuthenticationMethodServerTrust。
双向认证建立在单向认证的基础上,需要自己去额外实现:
双向认证中代理方法会收到两个类型的回调:
NSURLAuthenticationMethodServerTrust :服务端发送证书给客户端,客户端进行证书校验,默认操作是使用跟证书(CA证书)进行合法校验;NSURLAuthenticationMethodClientCertificate :服务端要求客户端提供证书,此时客户端应将工程中的证书解析并传递给服务端。服务端一般也是做证书链校验,如果是有限访问,还会做证书主体的校验;与会话层面的认证机制相对的是特殊任务认证机制:

这些枚举的意义是???(见后文)
TLS (Transport Layer Security)就是 SSL(Secure Socket Layer),只不过版本不同而已:

SSL 和 HTTPS 的概念等不再赘述;
HTTPS 中的单向认证流程图如下:

其具体的流程为:
简化版流程图如下:

一般的 HTTPS 请求都采用单向认证,只有极少数对安全性要求很高的企业采用双向认证如金融企业,或者是企业对涉及到核心业务的接口采用双向认证;
单向认证中客户端认证服务端证书的特性就决定了,只要客户端愿意且服务端的证书正常,那么任意客户端都可以访问该服务器;
双向认证中,除了客户端对服务端进行认证,服务端还要对客户端进行认证。因此,服务端对客户端证书的认证逻辑就决定了客户端是被动的,能否访问该服务器完全由服务端决定。有的服务端只是单纯的对客户端证书进行 CA 认证,还有的会对证书的主体进行认证,非白名单内的主体不允许访问服务器;
NTLM 和 Kerberos 用于早期的 Windows 中,本文不做过多了解:

双向认证和白名单有这相同的作用,就是服务端限制某些客户端的访问,白名单机制的存在有这更方面成熟的实现机制,可能这就是双向认证不常用的原因?
是指使用某种算法计算出元数据的哈希值,以此确保元数据没有被篡改,最初的签名算法采用摘要算法,证书体系中的签名采用摘要算法+ 非对称加密的方式进行签名;
因为黑客可以修改元数据的同时修改摘要算法得出的哈希值,所以出现了证书,其目的是通过非对称加密来保证元数据的哈希值不被破解;
证书分为 TBSCertificate(To-Be-Signed) 和 Certificate,即待签名的证书和签名过的证书。TBSCertificate 证书中包含拥有者的各种信息,同时还包含拥有者的公钥。我们一般说的证书是经过签名的,这种证书中除了包含 TBSCertificate ,还会包含签名使用的算法、签名值;
非对称加密效率较低,所以证书的签名一般先对 TBSCertificate 使用摘要算法得到固定长度的哈希值,然后使用私钥对这个哈希值进行非对称加密,最终得到签名,所以证书体系中的签名已经不是单纯的摘要算法了;
最初的证书是自签名证书,拥有者使用自己的私钥对 TBSCertificate 进行签名,如果黑客攻击了证书发送者,并将证书上的公钥替换为自己的公钥,甚至直接将拥有者的私钥给窃取或者替换,那么接收者接收到的也是被篡改过的数据;
自签名证书中,私人的私钥安全性隐患很大,因此才有了权威的 CA 机构,证书体系中默认 CA 机构的安全性不会被破解,所以理论上 CA 的私钥不会被窃取。CA 机构会对个人信息进行验证,并且使用自己的私钥对 TBSCertificate 证书进行签名之后颁发给申请者;
CA 机构的私钥理论上绝对安全,公钥会被嵌入到计算机基础体系中,如被嵌入到操作系统、浏览器中,所以浏览器可以直接使用 CA 的公钥对证书进行验签;
验签的流程就是先提取签名时使用的签名算法(signatureAlgorithm),这里主要是要知道签名时摘要算法采用的哪一种。然后提取出 TBSCertificate,使用摘要算法对 TBSCertificate 进行哈希,得到 Hash1。接着,使用 CA 公钥对签名值(signatureValue)进行解密,得到 Hash2,如果 Hash1 = Hash2,则证书校验成功;
至此,CA + 非对称加密 + 摘要算法就组成了证书体系;
Root CA 基本上就那几个,他们的公钥会被嵌入到计算机基础体系中。如果直接使用 Root CA 的公钥进行签发,那么一旦 Root CA 的私钥发生变化,如撤销、过期等,牵连范围极大。
所以 intermediate CA 出现了, intermediate CA 作为 Root CA 的代理,先向 Root CA 申请证书,其流程和上面的基本一致, intermediate CA 将自己的信息和公钥发送给 Root CA ,Root CA 验证信息后颁发 TBSCertificate 并使用自己的私钥进行签名,最后颁发给 intermediate CA;
Root CA 只对 intermediate CA 颁发证书, intermediate CA 使用自己的私钥对申请者的证书进行签名,这样就实现了代理的作用;
一张图做总结:

首先,三个随机数的正常使用流程如下:

最终客户端和服务端都有三个随机数,然后根据三个随机数使用协议中的算法计算出一个 master_random,后续都使用 master_random 对报文进行对称加密之后传输;
这里有几个重点:
要回答这两个问题,这里就涉及到 HTTPS 中计算对称加密最终 key 的两种算法:
HTTPS 中如果采用 RSA 加密,也就是通过 premaster_random 这一个随机数来计算最终的对称秘钥 master_random ,最后客户端使用 RSA 加密传输给服务端。后续服务端和客户端都是用这个随机数作为对称加密的 key 进行对称加密,这种情况有两个问题:
流程如下:

根据 RSA 算法的规则,RSA 只能暴力枚举,算力很强的计算机都要枚举 70 年,所以 RSA 基本无法破解。但是,需要注意的是,破解 HTTPS 的关键不在于破解 RSA,而在于获得对称秘钥。因为 RSA 算法只用在建立 HTTPS 的传输阶段,后续加密都是使用对称秘钥,所以一旦猜出了这个随机数,无需破解 RSA 就能破解 HTTPS。
因此,HTTPS 的安全攻防归根到底在于对称秘钥的加解密,只有这个随机数越随机,HTTPS 才越安全。上述算法中,这个随机数只在客户端生成,其最大的问题在于随机数的算法相对固定,那么就意味着:
因此,开发出了三个随机数的 HTTPS 加密。
上述过程中,客户端和服务端在握手 hello 消息中明文交换了client_random 和 server_random,使用 RSA 公钥加密传输premaster secret,最后通过算法,客户端和服务端分别计算 master secret。其中,不直接使用 premaster secret 的原因是:保证 secret 的随机性不受任意一方的影响。
这种三个随机数下的 HTTPS 已经相当安全了,理论上,只要服务器的公钥足够长(比如2048位),那么Premaster secret可以保证不被破解。但是为了足够安全,我们可以考虑把握手阶段的算法从默认的RSA算法,改为 Diffie-Hellman算法(简称DH算法)。
定义素数g、p(只有1和自身的因数)
g 和 p双方都知道,这里假如 g = 7, p = 5,实际上这两个值都是很大的。
双方计算大数 P = g^X mod p
Server 生成随机数 X2,假设 X2 = 5,P2 = 7^5 mod 5 => 16807 对 5 取模,结果为 2。
Client 生成随机数 X1,假设 X1 = 2,P1 = 7^2 mod 5 => 49 对 5 取模,结果为 4。
交换P1、P2
Client 有 p、g、X1、P2,Server有p、g、X2、P1。
计算密钥 S
利用S = g^X mod p 计算密钥,对应 Client,S1 = P2^X1 mod p = 4,
对应 Server,S2 = P1^X2 mod p = 4,S1=S2 恒成立。
采用DH算法后,Premaster secret不需要传递,双方只要交换各自的参数,就可以算出这个随机数。上图中,第三步和第四步由传递Premaster secret变成了传递DH算法所需的参数,然后双方各自算出Premaster secret。这样就提高了安全性。
本质上还是借鉴了分解质因数只能暴力枚举的原理;
流程如下:

DH 算法原理:https://blog.csdn.net/mrpre/article/details/52608867
更加详细的流程图:

如果不清楚上面的计算原理,只需要知道 DH 算法通过 3 个随机数来计算最终的 master_random 作为对称加密的 key,解决了伪随机数不一定随机的问题,还解决了 RSA 加密的向前攻击的问题;
为什么需要三个随机数,总结:
为什么伪随机数不一定随机?只要这个随机数是由确定算法生成的,那就是伪随机,也就是有规则的随机。所以知道了算法,下一个随机数是可以被计算出来的,所以,“随机”这个属性和算法本身就是矛盾的。
附-破解 HTTPS 的三种方法:

TCP报文格式:

序号:seq,用来标识从TCP源端向目的端发送的字节流。tcp中传输数据时,会把数据中的每个字节用序号进行标志,确保数据按顺序传输
确认号:ack,小写的。只有ACK标志位为1时,确认序号字段才有效,ack=Seq+1。确认方Ack=发起方Req+1,无论哪一端的确认号都是如此。比如A向B发送建立连接的请求时,seq=x,B回复的报文中 ACK 标志位为1,且确认号就是ack=x+1,表示收到了序列号为x的报文。
标志位:表示报文的六种格式,为1时才有效,默认为0;注意,ACK是标志位,而ack是确认号。
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
四次分手:
完整的通信流程:

总结:网络存在延迟、丢失的情况,两次握手会导致服务端开启多个无效连接,进而导致服务端在传送数据但是客户端并没有连接上的情况,而四次握手又多余了。
总结:客户端请求断开连接时,server有可能存在未发送完毕的数据,这种特性导致server将ACK和FIN报文分开发送,所以就会出现比三次握手时多一次的报文,三次握手时,server将ACK和SYN合并发送了;
结果:客户端和服务端的 master_random 是相同的,后面都使用这个数字作为对称加密的 key 来对数据进行对称加密之后进行传输;
ATS,即 App Transport Security,ATS 默认情况下要求 App 所有的请求都使用 HTTPS 连接,且对 HTTPS 认证中的摘要算法版本、对称算法版本等进行要求。Apple 利用自己的强势地位推动了客户端的安全性。
如果不额外在 info.plist 中设置 ATS,那么就相当于开启 ATS。
此时,所有的连接/请求都会被 ATS 机制拦截并使用 ATS 中默认的设置来进行连接的认证和建立,符合 ATS 要求的请求才能够通过,否则会被拒绝,ATS 默认策略的检测包括且不限于:
证书链的验证(层层验签,最终使用系统中的跟证书对 intermediate CA 进行验签),这个应该对应代码中的 X509 认证模式;
TLS 最低版本验证;
摘要算法最低版本验证;
默认会进行域名验证,域名认证就是对叶子节点的证书中的域名进行对比。AFN 早期版本默认是 X509 认证,即只验签,不认证域名,存在证书被劫持/替换的风险,该重大漏洞被曝出后 AFN 对其进行了修复;
默认策略没有锁定认证(SSL Pinning Mode),而 AFN 中对此模式进行了实现;
ATS 的三个设置项
最常用的两个设置就是 NSAllowsArbitraryLoads 和 NSAllowsArbitraryLoadsInWebContent。两者组合时,会根据版本的不同(是否大于 iOS10)而有不同的表现。鉴于现在的 iOS9 版本已经很少了,可以直接使用 iOS10 的版本,两个设置的优先级:NSAllowsArbitraryLoadsInWebContent > NSAllowsArbitraryLoads。即设置了前者之后,后者会被忽略;
如果需要完全关闭 ATS,需要设置 NSAllowsArbitraryLoads = YES,并且在提交审核时进行说明。
对于浏览器类 App,如果只是允许浏览器中使用非安全的请求(HTTP),那么只需要设置 NSAllowsArbitraryLoadsInWebContent = YES 即可。
另外,还可以使用 NSExceptionDomains 来设置允许 HTTP 请求的白名单域名,这种设置相对于直接关闭 ATS 更容易过审,使用如下:

可以直接使用该网站来检测所请求的域名是否符合 ATS 标准:https://myssl.com/ats.html?domain=mobi.yocaigs.com&port=443
如图:

ATS 的具体要求可以再官方文档中查阅:https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35
综上,如果公司使用的证书是 CA 申请下来的,且服务器端支持的加密算法符合 ATS 的要求,那么无论是 NSURLSession 还是 AFNetworking,都是可以直接进行网络请求的,Apple 已经完成了 HTTPS 中客户端对服务器证书的验证操作,不需要开发者额外实现而且安全性能够得到保证。
所以,ATS 是 Apple 对客户端请求的安全标准和实现(封装);
ATS(NSURLSession)中对 HTTPS 的默认实现采用的是单向认证策略,如果需要使用双向认证,则需要自己拦截
NSURLAuthenticationMethodClientCertificate并提供客户端的证书;
概念
证书锁定(SSL/TLS Pinning)顾名思义,将服务器提供的 SSL/TLS 证书内置到移动端开发的APP客户端中,当客户端发起请求时,通过比对内置的证书和服务器端证书的内容,以确定这个连接的合法性。
产生原因
因为 CA 证书签发机构也存在被黑客入侵的可能性,同时移动设备也面临内置证书被篡改的风险,或者是用户信任了不该信任的证书,这些情况都有可能导致证书链的不可靠。锁定认证模式本质是为了规避用户信任链不可靠带来的安全问题;
原理
我们需要将 APP 代码内置仅接受指定域名的证书,而不接受操作系统或浏览器内置的CA根证书对应的任何证书,通过这种授权方式,保障了 APP 与服务端通信的唯一性和安全性,因此我们移动端APP与服务端(例如 API 网关)之间的通信是可以保证绝对安全。
此种模式下,App 需要验证证书的签名,步骤如下:
理论上应该也可以在双向认证中,客户端发送证书给服务端进行验证;
使用签名校验的方式有一个缺点:
而公钥验证可以规避掉这个缺点,起流程如下:
我们在制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题;
TBSCetificate 包含有效期这个字段,颁发机构是对 TBSCertificate 进行签名的,所以有效期发生变化则整个签名都会发生变化。所以证书一旦过期,就需要更新 App 中的内置证书,对于 iOS 而言就需要发布新的版本,加之版本的兼容会比较复杂,所以公钥验证是一种比较合适的方案;
如果采用证书锁定方式(Certificate Mode),则获取证书的摘要 hash,以 infinisign.com 为例:
## 在线读取服务器端.cer格式证书
openssl s_client -connect infinisign.com:443 -showcerts < /dev/null | openssl x509 -outform DER > infinisign.der
## 提取证书的摘要hash并查看base64格式
openssl dgst -sha256 -binary infinisign.der | openssl enc -base64
wLgBEAGmLltnXbK6pzpvPMeOCTKZ0QwrWGem6DkNf6o=
所以其中的wLgBEAGmLltnXbK6pzpvPMeOCTKZ0QwrWGem6DkNf6o=就是我们将要进行证书锁定的指纹 (Hash) 信息。
如果采用公钥锁定方式(PublicKey Mode),则获取证书公钥的摘要hash,以infinisign.com为例
// 读取服务器端证书的公钥
openssl x509 -pubkey -noout -in infinisign.der -inform DER | openssl rsa -outform DER -pubin -in /dev/stdin 2>/dev/null > infinisign.pubkey
// 提取公钥的摘要hash并查看base64格式
openssl dgst -sha256 -binary infinisign.pubkey | openssl enc -base64
bAExy9pPp0EnzjAlYn1bsSEGvqYi1shl1OOshfH3XDA=
所以其中的bAExy9pPp0EnzjAlYn1bsSEGvqYi1shl1OOshfH3XDA=就是我们将要进行证书锁定的指纹 (Hash) 信息。
见文章:AFN中的鉴权
typedef NS_ENUM(NSInteger, XKHTTPClientSSLChallengeMode) {
XKHTTPClientSSLChallengeModeNone, // 忽略
XKHTTPClientSSLChallengeModeSimple, // 不校验host
XKHTTPClientSSLChallengeModeFull // 正常校验
};
不校验,对于访问的 server 直接信任。
此时,可以访问自签名证书的网站、证书过期的网站;
不校验域名
此时,使用 X509 的规则对证书进行校验,只要证书符合规则,且该证书的根节点存在于当前机器的证书链中。另外,如果自身机器中信任了某个证书,那么该证书会被添加到证书链中,使用该证书作为根节点的证书也会通过校验,所以是存在风险的;
正常校验
此时走 Apple 中 ATS 的默认实现,检测证书且校验域名;
代码如下:
-(void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
NSURLCredential * credential = nil;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if (self.sslChallengeMode == XKHTTPClientSSLChallengeModeNone) {
// 使用服务端的证书对服务端进行校验,那肯定是怎样都通过,自签名证书都能通过
disposition = NSURLSessionAuthChallengeUseCredential;
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
} else if(self.sslChallengeMode == XKHTTPClientSSLChallengeModeSimple) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
NSArray * policies = @[ (__bridge_transfer id)SecPolicyCreateBasicX509() ];
SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
SecTrustResultType result;
if(SecTrustEvaluate(serverTrust, &result) == errSecSuccess &&
(result == kSecTrustResultUnspecified || result == kSecTrustResultProceed)) {
// x509认证,不会对服务端证书中的域名和请求的域名进行一致性校验
// 校验成功,则直接传递服务端证书来对服务端鉴权进行校验,即:怎样都会成功
disposition = NSURLSessionAuthChallengeUseCredential;
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
} else {
// x509校验失败,则走默认的校验逻辑
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
// 默认校验逻辑:ATS,即对证书锚点、证书链进行校验且会对证书中的域名和请求的域名的一致性进行校验
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
if (completionHandler) {
completionHandler(disposition, credential);
}
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
NSURLCredential * credential = nil;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
disposition = NSURLSessionAuthChallengeUseCredential;
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
}
if (completionHandler) {
completionHandler(disposition, credential);
}
}
对于容器而言,这样做是合理的,因为浏览器可能会访问不安全的网站;
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if (!(self.options & UPSDWebImageDownloaderAllowInvalidSSLCertificates)) {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
} else {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
disposition = NSURLSessionAuthChallengeUseCredential;
}
} else {
if (challenge.previousFailureCount == 0) {
if (self.credential) {
credential = self.credential;
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
}
if (completionHandler) {
completionHandler(disposition, credential);
}
}
疑问:
参考:
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA