• 关于

    本地小程序教程api方案

    的搜索结果

回答

详细解答可以参考官方帮助文档 发送访问OSS的请求 您可以直接使用OSS提供的RESTful API接口访问或者使用对API接口进行完整封装的SDK开发包。而每一次向OSS的请求根据当前Bucket权限和操作不同要求用户进行身份验证或者直接匿名访问。对OSS的资源访问的分类如下: 按访问者的角色可分为拥有者访问和第三方用户访问。这里的拥有者指的是Bucket的Owner,也称为开发者。第三方用户是指访问Bucket里资源的用户。 按访问者的身份信息可分为匿名访问和带签名访问。对于OSS来说,如果请求中没有携带任何和身份相关的信息即为匿名访问。带签名访问指的是按照OSS API文档中规定的在请求头部或者在请求URL中携带签名的相关信息。 AccessKey 类型 目前访问 OSS 使用的 AK(AccessKey)有三种类型,具体如下: 阿里云账号AccessKey 阿里云账号AK特指Bucket拥有者的AK,每个阿里云账号提供的AccessKey对拥有的资源有完全的权限。每个阿里云账号能够同时拥有不超过5个active或者inactive的AK对(AccessKeyId和AccessKeySecret)。 用户可以登录AccessKey管理控制台,申请新增或删除AK对。 每个AK对都有active/inactive两种状态。 Active 表明用户的 AK 处于激活状态,可以在身份验证的时候使用。 Inactive 表明用户的 AK 处于非激活状态,不能在身份验证的时候使用。 说明 请避免直接使用阿里云账户的 AccessKey。 RAM子账号AccessKey RAM (Resource Access Management) 是阿里云提供的资源访问控制服务。RAM账号AK指的是通过RAM被授权的AK。这组AK只能按照RAM定义的规则去访问Bucket里的资源。通过RAM,您可以集中管理您的用户(比如员工、系统或应用程序),以及控制用户可以访问您名下哪些资源的权限。比如能够限制您的用户只拥有对某一个Bucket的读权限。子账号是从属于主账号的,并且这些账号下不能拥有实际的任何资源,所有资源都属于主账号。 STS账号AccessKey STS(Security Token Service)是阿里云提供的临时访问凭证服务。STS账号AK指的是通过STS颁发的AK。这组AK只能按照STS定义的规则去访问Bucket里的资源。 身份验证具体实现 目前主要有三种身份验证方式: AK验证 RAM验证 STS验证 当用户以个人身份向OSS发送请求时,其身份验证的实现如下: 用户将发送的请求按照OSS指定的格式生成签名字符串。 用户使用AccessKeySecret对签名字符串进行加密产生验证码。 OSS收到请求以后,通过AccessKeyId找到对应的AccessKeySecret,以同样的方法提取签名字符串和验证码。 如果计算出来的验证码和提供的一样即认为该请求是有效的。 否则,OSS将拒绝处理这次请求,并返回HTTP 403错误。 对于用户来说可以直接使用OSS提供的SDK,配合不同类型的AccessKey即可实现不同的身份验证。 权限控制 针对存放在Bucket的Object的访问,OSS提供了多种权限控制,主要有: Bucket级别权限 Object级别权限 账号级别权限(RAM) 临时账号权限(STS) Bucket级别权限 Bucket权限类型 OSS提供ACL(Access Control List)权限控制方法,OSS ACL提供Bucket级别的权限访问控制,Bucket目前有三种访问权限:public-read-write,public-read和private,它们的含义如下: 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 任何人(包括匿名访问)都可以对该Bucket中的Object进行读/写/删除操作;所有这些操作产生的费用由该Bucket的Owner承担,请慎用该权限。 public-read 公共读,私有写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行写/删除操作;任何人(包括匿名访问)可以对Object进行读操作。 private 私有读写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行读/写/删除操作;其他人在未经授权的情况下无法访问该Bucket内的Object。 Bucket权限设定和读取方法 功能使用参考: API:Put BucketACL SDK:Java SDK-设置Bucket ACL 控制台:创建Bucket权限设置 API:Get BucketACL SDK:Java SDK-获取Bucket ACL Object级别权限 Object权限类型 OSS ACL也提供Object级别的权限访问控制。目前Object有四种访问权限:private, public-read, public-read-write, default。Put Object ACL操作通过Put请求中的“x-oss-object-acl”头来设置,这个操作只有Bucket Owner有权限执行。 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 该ACL表明某个Object是公共读写资源,即所有用户拥有对该Object的读写权限。 public-read 公共读,私有写 该ACL表明某个Object是公共读资源,即非Object Owner只有该Object的读权限,而Object Owner拥有该Object的读写权限。 private 私有读写 该ACL表明某个Object是私有资源,即只有该Object的Owner拥有该Object的读写权限,其他的用户没有权限操作该Object。 default 默认权限 该ACL表明某个Object是遵循Bucket读写权限的资源,即Bucket是什么权限,Object就是什么权限。 说明 如果没有设置Object的权限,即Object的ACL为default,Object的权限和Bucket权限一致。 如果设置了Object的权限,Object的权限大于Bucket权限。举个例子,如果设置了Object的权限是public-read,无论Bucket是什么权限,该Object都可以被身份验证访问和匿名访问。 Object权限设定和读取方法 功能使用参考: API:Put Object ACL SDK:Java SDK-ObjectACL 中设定Object ACL API:Get Object ACL SDK:Java SDK-ObjectACL 中读取Object ACL 账号级别权限(RAM) 使用场景 如果您购买了云资源,您的组织里有多个用户需要使用这些云资源,这些用户只能共享使用您的云账号AccessKey。这里有两个问题: 您的密钥由多人共享,泄露的风险很高。 您无法控制特定用户能访问哪些资源(比如Bucket)的权限。 解决方法:在您的阿里云账号下面,通过RAM可以创建具有自己AccessKey的子用户。您的阿里云账号被称为主账号,创建出来的账号被称为子账号,使用子账号的AccessKey只能使用主账号授权的操作和资源。 具体实现 有关RAM详情,请参考RAM用户手册。 对于授权中需要的Policy的配置方式可以参考本章最后一节:RAM和STS授权策略(Policy)配置。 临时账号权限(STS) 使用场景 对于您本地身份系统所管理的用户,比如您的App的用户、您的企业本地账号、第三方App,也有直接访问OSS资源的可能,将这部分用户称为联盟用户。此外,用户还可以是您创建的能访问您的阿里云资源的应用程序。 对于这部分联盟用户,通过阿里云STS (Security Token Service) 服务为阿里云账号(或RAM用户)提供短期访问权限管理。您不需要透露云账号(或RAM用户)的长期密钥(如登录密码、AccessKey),只需要生成一个短期访问凭证给联盟用户使用即可。这个凭证的访问权限及有效期限都可以由您自定义。您不需要关心权限撤销问题,访问凭证过期后会自动失效。 用户通过STS生成的凭证包括安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)。使用AccessKey方法与您在使用阿里云账户或RAM用户AccessKey发送请求时的方法相同。此外还需要注意的是在每个向OSS发送的请求中必须携带安全令牌。 具体实现 STS安全令牌、角色管理和使用相关内容详情,请参考RAM用户指南中的角色管理。关键是调用STS服务接口AssumeRole来获取有效访问凭证即可,也可以直接使用STS SDK来调用该方法。 RAM和STS应用场景实践 对于不同的应用场景,涉及到的访问身份验证方式可能存在差异。下面以几种典型的应用场景来说明访问身份验证中几种使用方式。 以一个移动App举例。假设您是一个移动App开发者,打算使用阿里云OSS服务来保存App的终端用户数据,并且要保证每个App用户之间的数据隔离,防止一个App用户获取到其它App用户的数据。 方式一:使用AppServer来做数据中转和数据隔离如上图所示,您需要开发一个AppServer。只有AppServer能访问云服务,ClientApp的每次读写数据都需要通过AppServer,AppServer来保证不同用户数据的隔离访问。 对于该种使用方式,使用阿里云账号或者RAM账号提供的密钥来进行签名验证访问。建议您尽量不要直接使用阿里云账号(主账号)的密钥访问OSS,避免出现安全问题。 方式二:使用STS让用户直接访问OSS STS方案描述如下图所示:方案的详细描述如下: App用户登录。App用户和云账号无关,它是App的终端用户,AppServer支持App用户登录。对于每个有效的App用户来说,需要AppServer能定义出每个App用户的最小访问权限。 AppServer请求STS服务获取一个安全令牌(SecurityToken)。在调用STS之前,AppServer需要确定App用户的最小访问权限(用Policy语法描述)以及授权的过期时间。然后通过扮演角色(AssumeRole)来获取一个代表角色身份的安全令牌。 STS返回给AppServer一个有效的访问凭证,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)以及过期时间。 AppServer将访问凭证返回给ClientApp。ClientApp可以缓存这个凭证。当凭证失效时,ClientApp需要向AppServer申请新的有效访问凭证。比如,访问凭证有效期为1小时,那么ClientApp可以每30分钟向AppServer请求更新访问凭证。 ClientApp使用本地缓存的访问凭证去请求Aliyun Service API。云服务会感知STS访问凭证,并会依赖STS服务来验证访问凭证,正确响应用户请求。 RAM和STS授权策略(Policy)配置 对于RAM或者STS授权中使用Policy,详细规则如下。 示例 先看下面的一个Policy示例: { "Version": "1", "Statement": [ { "Action": [ "oss:GetBucketAcl", "oss:ListObjects" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket" ], "Effect": "Allow", "Condition": { "StringEquals": { "acs:UserAgent": "java-sdk", "oss:Prefix": "foo" }, "IpAddress": { "acs:SourceIp": "192.168.0.1" } } }, { "Action": [ "oss:PutObject", "oss:GetObject", "oss:DeleteObject" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket/file*" ], "Effect": "Allow", "Condition": { "IpAddress": { "acs:SourceIp": "192.168.0.1" } } } ] } 这是一个授权的Policy,用户用这样的一个Policy通过RAM或STS服务向其他用户授权。Policy当中有一个Statement(一条Policy当中可以有多条Statement)。Statement里面规定了相应的Action、Resource、Effect和Condition。 这条Policy把用户自己名下的mybucket和mybucket/file*这些资源授权给相应的用户,并且支持GetBucketAcl、GetBucket、PutObject、GetObject和DeleteObject这几种操作。Condition中的条件表示UserAgent为java-sdk,源IP为192.168.0.1的时候鉴权才能通过,被授权的用户才能访问相关的资源。Prefix这个Condition是在GetBucket(ListObjects)的时候起作用的,关于这个字段的解释详见OSS的API文档。 配置细则 Version Version定义了Policy的版本,本文档中sw2q的配置方式,设置为1。 Statement 通过Statement描述授权语义,其中可以根据业务场景包含多条语义,每条包含对Action、Effect、Resource和Condition的描述。每次请求系统会逐条依次匹配检查,所有匹配成功的Statement会根据Effect的设置不同分为通过(Allow)、禁止(Deny),其中禁止(Deny)的优先。如果匹配成功的都为通过,该条请求即鉴权通过。如果匹配成功有一条禁止,或者没有任何条目匹配成功,该条请求被禁止访问。 Action Action分为三大类:Service级别操作,对应的是GetService操作,用来列出所有属于该用户的Bucket列表。 Bucket级别操作,对应类似于oss:PutBucketAcl、oss:GetBucketLocation之类的操作,操作的对象是Bucket,它们的名称和相应的接口名称一一对应。 Object级别操作,分为oss:GetObject、oss:PutObject、oss:DeleteObject和oss:AbortMultipartUpload,操作对象是Object。 如想授权某一类的Object的操作,可以选择这几种的一种或几种。另外,所有的Action前面都必须加上oss:,如上面例子所示。Action是一个列表,可以有多个Action。具体的Action和API接口的对应关系如下: Service级别 API Action GetService(ListBuckets) oss:ListBuckets Bucket级别 API Action PutBucket oss:PutBucket GetBucket(ListObjects) oss:ListObjects PutBucketAcl oss:PutBucketAcl DeleteBucket oss:DeleteBucket GetBucketLocation oss:GetBucketLocation GetBucketAcl oss:GetBucketAcl GetBucketLogging oss:GetBucketLogging PutBucketLogging oss:PutBucketLogging DeleteBucketLogging oss:DeleteBucketLogging GetBucketWebsite oss:GetBucketWebsite PutBucketWebsite oss:PutBucketWebsite DeleteBucketWebsite oss:DeleteBucketWebsite GetBucketReferer oss:GetBucketReferer PutBucketReferer oss:PutBucketReferer GetBucketLifecycle oss:GetBucketLifecycle PutBucketLifecycle oss:PutBucketLifecycle DeleteBucketLifecycle oss:DeleteBucketLifecycle ListMultipartUploads oss:ListMultipartUploads PutBucketCors oss:PutBucketCors GetBucketCors oss:GetBucketCors DeleteBucketCors oss:DeleteBucketCors PutBucketReplication oss:PutBucketReplication GetBucketReplication oss:GetBucketReplication DeleteBucketReplication oss:DeleteBucketReplication GetBucketReplicationLocation oss:GetBucketReplicationLocation GetBucketReplicationProgress oss:GetBucketReplicationProgress Object级别 API Action GetObject oss:GetObject HeadObject oss:GetObject PutObject oss:PutObject PostObject oss:PutObject InitiateMultipartUpload oss:PutObject UploadPart oss:PutObject CompleteMultipart oss:PutObject DeleteObject oss:DeleteObject DeleteMultipartObjects oss:DeleteObject AbortMultipartUpload oss:AbortMultipartUpload ListParts oss:ListParts CopyObject oss:GetObject,oss:PutObject UploadPartCopy oss:GetObject,oss:PutObject AppendObject oss:PutObject GetObjectAcl oss:GetObjectAcl PutObjectAcl oss:PutObjectAcl Resource Resource指代的是OSS上面的某个具体的资源或者某些资源(支持*通配),resource的规则是acs:oss:{region}:{bucket_owner}:{bucket_name}/{object_name}。对于所有Bucket级别的操作来说不需要最后的斜杠和{object_name},即acs:oss:{region}:{bucket_owner}:{bucket_name}。Resource也是一个列表,可以有多个Resource。其中的region字段暂时不做支持,设置为*。 Effect Effect代表本条的Statement的授权的结果,分为Allow和Deny,分别指代通过和禁止。多条Statement同时匹配成功时,禁止(Deny)的优先级更高。 例如,期望禁止用户对某一目录进行删除,但对于其他文件有全部权限: { "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:*" ], "Resource": [ "acs:oss:*:*:bucketname" ] }, { "Effect": "Deny", "Action": [ "oss:DeleteObject" ], "Resource": [ "acs:oss:*:*:bucketname/index/*", ] } ] } Condition Condition代表Policy授权的一些条件,上面的示例里面可以设置对于acs:UserAgent的检查、acs:SourceIp的检查、还有oss:Prefix这项用来在GetBucket的时候对资源进行限制。 OSS支持的Condition如下: condition 功能 合法取值 acs:SourceIp 指定ip网段 普通的ip,支持*通配 acs:UserAgent 指定http useragent头 字符串 acs:CurrentTime 指定合法的访问时间 ISO8601格式 acs:SecureTransport 是否是https协议 “true”或者”false” oss:Prefix 用作ListObjects时的prefix 合法的object name 更多示例 针对具体场景更多的授权策略配置示例,可以参考教程示例:控制存储空间和文件夹的访问权限和OSS授权常见问题。 Policy在线图形化便捷配置工具,请单击这里。 最佳实践 RAM和STS使用指南

2019-12-01 23:12:47 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 发送访问OSS的请求 您可以直接使用OSS提供的RESTful API接口访问或者使用对API接口进行完整封装的SDK开发包。而每一次向OSS的请求根据当前Bucket权限和操作不同要求用户进行身份验证或者直接匿名访问。对OSS的资源访问的分类如下: 按访问者的角色可分为拥有者访问和第三方用户访问。这里的拥有者指的是Bucket的Owner,也称为开发者。第三方用户是指访问Bucket里资源的用户。 按访问者的身份信息可分为匿名访问和带签名访问。对于OSS来说,如果请求中没有携带任何和身份相关的信息即为匿名访问。带签名访问指的是按照OSS API文档中规定的在请求头部或者在请求URL中携带签名的相关信息。 AccessKey 类型 目前访问 OSS 使用的 AK(AccessKey)有三种类型,具体如下: 阿里云账号AccessKey 阿里云账号AK特指Bucket拥有者的AK,每个阿里云账号提供的AccessKey对拥有的资源有完全的权限。每个阿里云账号能够同时拥有不超过5个active或者inactive的AK对(AccessKeyId和AccessKeySecret)。 用户可以登录AccessKey管理控制台,申请新增或删除AK对。 每个AK对都有active/inactive两种状态。 Active 表明用户的 AK 处于激活状态,可以在身份验证的时候使用。 Inactive 表明用户的 AK 处于非激活状态,不能在身份验证的时候使用。 说明 请避免直接使用阿里云账户的 AccessKey。 RAM子账号AccessKey RAM (Resource Access Management) 是阿里云提供的资源访问控制服务。RAM账号AK指的是通过RAM被授权的AK。这组AK只能按照RAM定义的规则去访问Bucket里的资源。通过RAM,您可以集中管理您的用户(比如员工、系统或应用程序),以及控制用户可以访问您名下哪些资源的权限。比如能够限制您的用户只拥有对某一个Bucket的读权限。子账号是从属于主账号的,并且这些账号下不能拥有实际的任何资源,所有资源都属于主账号。 STS账号AccessKey STS(Security Token Service)是阿里云提供的临时访问凭证服务。STS账号AK指的是通过STS颁发的AK。这组AK只能按照STS定义的规则去访问Bucket里的资源。 身份验证具体实现 目前主要有三种身份验证方式: AK验证 RAM验证 STS验证 当用户以个人身份向OSS发送请求时,其身份验证的实现如下: 用户将发送的请求按照OSS指定的格式生成签名字符串。 用户使用AccessKeySecret对签名字符串进行加密产生验证码。 OSS收到请求以后,通过AccessKeyId找到对应的AccessKeySecret,以同样的方法提取签名字符串和验证码。 如果计算出来的验证码和提供的一样即认为该请求是有效的。 否则,OSS将拒绝处理这次请求,并返回HTTP 403错误。 对于用户来说可以直接使用OSS提供的SDK,配合不同类型的AccessKey即可实现不同的身份验证。 权限控制 针对存放在Bucket的Object的访问,OSS提供了多种权限控制,主要有: Bucket级别权限 Object级别权限 账号级别权限(RAM) 临时账号权限(STS) Bucket级别权限 Bucket权限类型 OSS提供ACL(Access Control List)权限控制方法,OSS ACL提供Bucket级别的权限访问控制,Bucket目前有三种访问权限:public-read-write,public-read和private,它们的含义如下: 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 任何人(包括匿名访问)都可以对该Bucket中的Object进行读/写/删除操作;所有这些操作产生的费用由该Bucket的Owner承担,请慎用该权限。 public-read 公共读,私有写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行写/删除操作;任何人(包括匿名访问)可以对Object进行读操作。 private 私有读写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行读/写/删除操作;其他人在未经授权的情况下无法访问该Bucket内的Object。 Bucket权限设定和读取方法 功能使用参考: API:Put BucketACL SDK:Java SDK-设置Bucket ACL 控制台:创建Bucket权限设置 API:Get BucketACL SDK:Java SDK-获取Bucket ACL Object级别权限 Object权限类型 OSS ACL也提供Object级别的权限访问控制。目前Object有四种访问权限:private, public-read, public-read-write, default。Put Object ACL操作通过Put请求中的“x-oss-object-acl”头来设置,这个操作只有Bucket Owner有权限执行。 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 该ACL表明某个Object是公共读写资源,即所有用户拥有对该Object的读写权限。 public-read 公共读,私有写 该ACL表明某个Object是公共读资源,即非Object Owner只有该Object的读权限,而Object Owner拥有该Object的读写权限。 private 私有读写 该ACL表明某个Object是私有资源,即只有该Object的Owner拥有该Object的读写权限,其他的用户没有权限操作该Object。 default 默认权限 该ACL表明某个Object是遵循Bucket读写权限的资源,即Bucket是什么权限,Object就是什么权限。 说明 如果没有设置Object的权限,即Object的ACL为default,Object的权限和Bucket权限一致。 如果设置了Object的权限,Object的权限大于Bucket权限。举个例子,如果设置了Object的权限是public-read,无论Bucket是什么权限,该Object都可以被身份验证访问和匿名访问。 Object权限设定和读取方法 功能使用参考: API:Put Object ACL SDK:Java SDK-ObjectACL 中设定Object ACL API:Get Object ACL SDK:Java SDK-ObjectACL 中读取Object ACL 账号级别权限(RAM) 使用场景 如果您购买了云资源,您的组织里有多个用户需要使用这些云资源,这些用户只能共享使用您的云账号AccessKey。这里有两个问题: 您的密钥由多人共享,泄露的风险很高。 您无法控制特定用户能访问哪些资源(比如Bucket)的权限。 解决方法:在您的阿里云账号下面,通过RAM可以创建具有自己AccessKey的子用户。您的阿里云账号被称为主账号,创建出来的账号被称为子账号,使用子账号的AccessKey只能使用主账号授权的操作和资源。 具体实现 有关RAM详情,请参考RAM用户手册。 对于授权中需要的Policy的配置方式可以参考本章最后一节:RAM和STS授权策略(Policy)配置。 临时账号权限(STS) 使用场景 对于您本地身份系统所管理的用户,比如您的App的用户、您的企业本地账号、第三方App,也有直接访问OSS资源的可能,将这部分用户称为联盟用户。此外,用户还可以是您创建的能访问您的阿里云资源的应用程序。 对于这部分联盟用户,通过阿里云STS (Security Token Service) 服务为阿里云账号(或RAM用户)提供短期访问权限管理。您不需要透露云账号(或RAM用户)的长期密钥(如登录密码、AccessKey),只需要生成一个短期访问凭证给联盟用户使用即可。这个凭证的访问权限及有效期限都可以由您自定义。您不需要关心权限撤销问题,访问凭证过期后会自动失效。 用户通过STS生成的凭证包括安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)。使用AccessKey方法与您在使用阿里云账户或RAM用户AccessKey发送请求时的方法相同。此外还需要注意的是在每个向OSS发送的请求中必须携带安全令牌。 具体实现 STS安全令牌、角色管理和使用相关内容详情,请参考RAM用户指南中的角色管理。关键是调用STS服务接口AssumeRole来获取有效访问凭证即可,也可以直接使用STS SDK来调用该方法。 RAM和STS应用场景实践 对于不同的应用场景,涉及到的访问身份验证方式可能存在差异。下面以几种典型的应用场景来说明访问身份验证中几种使用方式。 以一个移动App举例。假设您是一个移动App开发者,打算使用阿里云OSS服务来保存App的终端用户数据,并且要保证每个App用户之间的数据隔离,防止一个App用户获取到其它App用户的数据。 方式一:使用AppServer来做数据中转和数据隔离如上图所示,您需要开发一个AppServer。只有AppServer能访问云服务,ClientApp的每次读写数据都需要通过AppServer,AppServer来保证不同用户数据的隔离访问。 对于该种使用方式,使用阿里云账号或者RAM账号提供的密钥来进行签名验证访问。建议您尽量不要直接使用阿里云账号(主账号)的密钥访问OSS,避免出现安全问题。 方式二:使用STS让用户直接访问OSS STS方案描述如下图所示:方案的详细描述如下: App用户登录。App用户和云账号无关,它是App的终端用户,AppServer支持App用户登录。对于每个有效的App用户来说,需要AppServer能定义出每个App用户的最小访问权限。 AppServer请求STS服务获取一个安全令牌(SecurityToken)。在调用STS之前,AppServer需要确定App用户的最小访问权限(用Policy语法描述)以及授权的过期时间。然后通过扮演角色(AssumeRole)来获取一个代表角色身份的安全令牌。 STS返回给AppServer一个有效的访问凭证,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)以及过期时间。 AppServer将访问凭证返回给ClientApp。ClientApp可以缓存这个凭证。当凭证失效时,ClientApp需要向AppServer申请新的有效访问凭证。比如,访问凭证有效期为1小时,那么ClientApp可以每30分钟向AppServer请求更新访问凭证。 ClientApp使用本地缓存的访问凭证去请求Aliyun Service API。云服务会感知STS访问凭证,并会依赖STS服务来验证访问凭证,正确响应用户请求。 RAM和STS授权策略(Policy)配置 对于RAM或者STS授权中使用Policy,详细规则如下。 示例 先看下面的一个Policy示例: { "Version": "1", "Statement": [ { "Action": [ "oss:GetBucketAcl", "oss:ListObjects" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket" ], "Effect": "Allow", "Condition": { "StringEquals": { "acs:UserAgent": "java-sdk", "oss:Prefix": "foo" }, "IpAddress": { "acs:SourceIp": "192.168.0.1" } } }, { "Action": [ "oss:PutObject", "oss:GetObject", "oss:DeleteObject" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket/file*" ], "Effect": "Allow", "Condition": { "IpAddress": { "acs:SourceIp": "192.168.0.1" } } } ] } 这是一个授权的Policy,用户用这样的一个Policy通过RAM或STS服务向其他用户授权。Policy当中有一个Statement(一条Policy当中可以有多条Statement)。Statement里面规定了相应的Action、Resource、Effect和Condition。 这条Policy把用户自己名下的mybucket和mybucket/file*这些资源授权给相应的用户,并且支持GetBucketAcl、GetBucket、PutObject、GetObject和DeleteObject这几种操作。Condition中的条件表示UserAgent为java-sdk,源IP为192.168.0.1的时候鉴权才能通过,被授权的用户才能访问相关的资源。Prefix这个Condition是在GetBucket(ListObjects)的时候起作用的,关于这个字段的解释详见OSS的API文档。 配置细则 Version Version定义了Policy的版本,本文档中sw2q的配置方式,设置为1。 Statement 通过Statement描述授权语义,其中可以根据业务场景包含多条语义,每条包含对Action、Effect、Resource和Condition的描述。每次请求系统会逐条依次匹配检查,所有匹配成功的Statement会根据Effect的设置不同分为通过(Allow)、禁止(Deny),其中禁止(Deny)的优先。如果匹配成功的都为通过,该条请求即鉴权通过。如果匹配成功有一条禁止,或者没有任何条目匹配成功,该条请求被禁止访问。 Action Action分为三大类:Service级别操作,对应的是GetService操作,用来列出所有属于该用户的Bucket列表。 Bucket级别操作,对应类似于oss:PutBucketAcl、oss:GetBucketLocation之类的操作,操作的对象是Bucket,它们的名称和相应的接口名称一一对应。 Object级别操作,分为oss:GetObject、oss:PutObject、oss:DeleteObject和oss:AbortMultipartUpload,操作对象是Object。 如想授权某一类的Object的操作,可以选择这几种的一种或几种。另外,所有的Action前面都必须加上oss:,如上面例子所示。Action是一个列表,可以有多个Action。具体的Action和API接口的对应关系如下: Service级别 API Action GetService(ListBuckets) oss:ListBuckets Bucket级别 API Action PutBucket oss:PutBucket GetBucket(ListObjects) oss:ListObjects PutBucketAcl oss:PutBucketAcl DeleteBucket oss:DeleteBucket GetBucketLocation oss:GetBucketLocation GetBucketAcl oss:GetBucketAcl GetBucketLogging oss:GetBucketLogging PutBucketLogging oss:PutBucketLogging DeleteBucketLogging oss:DeleteBucketLogging GetBucketWebsite oss:GetBucketWebsite PutBucketWebsite oss:PutBucketWebsite DeleteBucketWebsite oss:DeleteBucketWebsite GetBucketReferer oss:GetBucketReferer PutBucketReferer oss:PutBucketReferer GetBucketLifecycle oss:GetBucketLifecycle PutBucketLifecycle oss:PutBucketLifecycle DeleteBucketLifecycle oss:DeleteBucketLifecycle ListMultipartUploads oss:ListMultipartUploads PutBucketCors oss:PutBucketCors GetBucketCors oss:GetBucketCors DeleteBucketCors oss:DeleteBucketCors PutBucketReplication oss:PutBucketReplication GetBucketReplication oss:GetBucketReplication DeleteBucketReplication oss:DeleteBucketReplication GetBucketReplicationLocation oss:GetBucketReplicationLocation GetBucketReplicationProgress oss:GetBucketReplicationProgress Object级别 API Action GetObject oss:GetObject HeadObject oss:GetObject PutObject oss:PutObject PostObject oss:PutObject InitiateMultipartUpload oss:PutObject UploadPart oss:PutObject CompleteMultipart oss:PutObject DeleteObject oss:DeleteObject DeleteMultipartObjects oss:DeleteObject AbortMultipartUpload oss:AbortMultipartUpload ListParts oss:ListParts CopyObject oss:GetObject,oss:PutObject UploadPartCopy oss:GetObject,oss:PutObject AppendObject oss:PutObject GetObjectAcl oss:GetObjectAcl PutObjectAcl oss:PutObjectAcl Resource Resource指代的是OSS上面的某个具体的资源或者某些资源(支持*通配),resource的规则是acs:oss:{region}:{bucket_owner}:{bucket_name}/{object_name}。对于所有Bucket级别的操作来说不需要最后的斜杠和{object_name},即acs:oss:{region}:{bucket_owner}:{bucket_name}。Resource也是一个列表,可以有多个Resource。其中的region字段暂时不做支持,设置为*。 Effect Effect代表本条的Statement的授权的结果,分为Allow和Deny,分别指代通过和禁止。多条Statement同时匹配成功时,禁止(Deny)的优先级更高。 例如,期望禁止用户对某一目录进行删除,但对于其他文件有全部权限: { "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:*" ], "Resource": [ "acs:oss:*:*:bucketname" ] }, { "Effect": "Deny", "Action": [ "oss:DeleteObject" ], "Resource": [ "acs:oss:*:*:bucketname/index/*", ] } ] } Condition Condition代表Policy授权的一些条件,上面的示例里面可以设置对于acs:UserAgent的检查、acs:SourceIp的检查、还有oss:Prefix这项用来在GetBucket的时候对资源进行限制。 OSS支持的Condition如下: condition 功能 合法取值 acs:SourceIp 指定ip网段 普通的ip,支持*通配 acs:UserAgent 指定http useragent头 字符串 acs:CurrentTime 指定合法的访问时间 ISO8601格式 acs:SecureTransport 是否是https协议 “true”或者”false” oss:Prefix 用作ListObjects时的prefix 合法的object name 更多示例 针对具体场景更多的授权策略配置示例,可以参考教程示例:控制存储空间和文件夹的访问权限和OSS授权常见问题。 Policy在线图形化便捷配置工具,请单击这里。 最佳实践 RAM和STS使用指南

2019-12-01 23:12:47 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 发送访问OSS的请求 您可以直接使用OSS提供的RESTful API接口访问或者使用对API接口进行完整封装的SDK开发包。而每一次向OSS的请求根据当前Bucket权限和操作不同要求用户进行身份验证或者直接匿名访问。对OSS的资源访问的分类如下: 按访问者的角色可分为拥有者访问和第三方用户访问。这里的拥有者指的是Bucket的Owner,也称为开发者。第三方用户是指访问Bucket里资源的用户。 按访问者的身份信息可分为匿名访问和带签名访问。对于OSS来说,如果请求中没有携带任何和身份相关的信息即为匿名访问。带签名访问指的是按照OSS API文档中规定的在请求头部或者在请求URL中携带签名的相关信息。 AccessKey 类型 目前访问 OSS 使用的 AK(AccessKey)有三种类型,具体如下: 阿里云账号AccessKey 阿里云账号AK特指Bucket拥有者的AK,每个阿里云账号提供的AccessKey对拥有的资源有完全的权限。每个阿里云账号能够同时拥有不超过5个active或者inactive的AK对(AccessKeyId和AccessKeySecret)。 用户可以登录AccessKey管理控制台,申请新增或删除AK对。 每个AK对都有active/inactive两种状态。 Active 表明用户的 AK 处于激活状态,可以在身份验证的时候使用。 Inactive 表明用户的 AK 处于非激活状态,不能在身份验证的时候使用。 说明 请避免直接使用阿里云账户的 AccessKey。 RAM子账号AccessKey RAM (Resource Access Management) 是阿里云提供的资源访问控制服务。RAM账号AK指的是通过RAM被授权的AK。这组AK只能按照RAM定义的规则去访问Bucket里的资源。通过RAM,您可以集中管理您的用户(比如员工、系统或应用程序),以及控制用户可以访问您名下哪些资源的权限。比如能够限制您的用户只拥有对某一个Bucket的读权限。子账号是从属于主账号的,并且这些账号下不能拥有实际的任何资源,所有资源都属于主账号。 STS账号AccessKey STS(Security Token Service)是阿里云提供的临时访问凭证服务。STS账号AK指的是通过STS颁发的AK。这组AK只能按照STS定义的规则去访问Bucket里的资源。 身份验证具体实现 目前主要有三种身份验证方式: AK验证 RAM验证 STS验证 当用户以个人身份向OSS发送请求时,其身份验证的实现如下: 用户将发送的请求按照OSS指定的格式生成签名字符串。 用户使用AccessKeySecret对签名字符串进行加密产生验证码。 OSS收到请求以后,通过AccessKeyId找到对应的AccessKeySecret,以同样的方法提取签名字符串和验证码。 如果计算出来的验证码和提供的一样即认为该请求是有效的。 否则,OSS将拒绝处理这次请求,并返回HTTP 403错误。 对于用户来说可以直接使用OSS提供的SDK,配合不同类型的AccessKey即可实现不同的身份验证。 权限控制 针对存放在Bucket的Object的访问,OSS提供了多种权限控制,主要有: Bucket级别权限 Object级别权限 账号级别权限(RAM) 临时账号权限(STS) Bucket级别权限 Bucket权限类型 OSS提供ACL(Access Control List)权限控制方法,OSS ACL提供Bucket级别的权限访问控制,Bucket目前有三种访问权限:public-read-write,public-read和private,它们的含义如下: 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 任何人(包括匿名访问)都可以对该Bucket中的Object进行读/写/删除操作;所有这些操作产生的费用由该Bucket的Owner承担,请慎用该权限。 public-read 公共读,私有写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行写/删除操作;任何人(包括匿名访问)可以对Object进行读操作。 private 私有读写 只有该Bucket的Owner或者授权对象可以对存放在其中的Object进行读/写/删除操作;其他人在未经授权的情况下无法访问该Bucket内的Object。 Bucket权限设定和读取方法 功能使用参考: API:Put BucketACL SDK:Java SDK-设置Bucket ACL 控制台:创建Bucket权限设置 API:Get BucketACL SDK:Java SDK-获取Bucket ACL Object级别权限 Object权限类型 OSS ACL也提供Object级别的权限访问控制。目前Object有四种访问权限:private, public-read, public-read-write, default。Put Object ACL操作通过Put请求中的“x-oss-object-acl”头来设置,这个操作只有Bucket Owner有权限执行。 权限值 中文名称 权限对访问者的限制 public-read-write 公共读写 该ACL表明某个Object是公共读写资源,即所有用户拥有对该Object的读写权限。 public-read 公共读,私有写 该ACL表明某个Object是公共读资源,即非Object Owner只有该Object的读权限,而Object Owner拥有该Object的读写权限。 private 私有读写 该ACL表明某个Object是私有资源,即只有该Object的Owner拥有该Object的读写权限,其他的用户没有权限操作该Object。 default 默认权限 该ACL表明某个Object是遵循Bucket读写权限的资源,即Bucket是什么权限,Object就是什么权限。 说明 如果没有设置Object的权限,即Object的ACL为default,Object的权限和Bucket权限一致。 如果设置了Object的权限,Object的权限大于Bucket权限。举个例子,如果设置了Object的权限是public-read,无论Bucket是什么权限,该Object都可以被身份验证访问和匿名访问。 Object权限设定和读取方法 功能使用参考: API:Put Object ACL SDK:Java SDK-ObjectACL 中设定Object ACL API:Get Object ACL SDK:Java SDK-ObjectACL 中读取Object ACL 账号级别权限(RAM) 使用场景 如果您购买了云资源,您的组织里有多个用户需要使用这些云资源,这些用户只能共享使用您的云账号AccessKey。这里有两个问题: 您的密钥由多人共享,泄露的风险很高。 您无法控制特定用户能访问哪些资源(比如Bucket)的权限。 解决方法:在您的阿里云账号下面,通过RAM可以创建具有自己AccessKey的子用户。您的阿里云账号被称为主账号,创建出来的账号被称为子账号,使用子账号的AccessKey只能使用主账号授权的操作和资源。 具体实现 有关RAM详情,请参考RAM用户手册。 对于授权中需要的Policy的配置方式可以参考本章最后一节:RAM和STS授权策略(Policy)配置。 临时账号权限(STS) 使用场景 对于您本地身份系统所管理的用户,比如您的App的用户、您的企业本地账号、第三方App,也有直接访问OSS资源的可能,将这部分用户称为联盟用户。此外,用户还可以是您创建的能访问您的阿里云资源的应用程序。 对于这部分联盟用户,通过阿里云STS (Security Token Service) 服务为阿里云账号(或RAM用户)提供短期访问权限管理。您不需要透露云账号(或RAM用户)的长期密钥(如登录密码、AccessKey),只需要生成一个短期访问凭证给联盟用户使用即可。这个凭证的访问权限及有效期限都可以由您自定义。您不需要关心权限撤销问题,访问凭证过期后会自动失效。 用户通过STS生成的凭证包括安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)。使用AccessKey方法与您在使用阿里云账户或RAM用户AccessKey发送请求时的方法相同。此外还需要注意的是在每个向OSS发送的请求中必须携带安全令牌。 具体实现 STS安全令牌、角色管理和使用相关内容详情,请参考RAM用户指南中的角色管理。关键是调用STS服务接口AssumeRole来获取有效访问凭证即可,也可以直接使用STS SDK来调用该方法。 RAM和STS应用场景实践 对于不同的应用场景,涉及到的访问身份验证方式可能存在差异。下面以几种典型的应用场景来说明访问身份验证中几种使用方式。 以一个移动App举例。假设您是一个移动App开发者,打算使用阿里云OSS服务来保存App的终端用户数据,并且要保证每个App用户之间的数据隔离,防止一个App用户获取到其它App用户的数据。 方式一:使用AppServer来做数据中转和数据隔离如上图所示,您需要开发一个AppServer。只有AppServer能访问云服务,ClientApp的每次读写数据都需要通过AppServer,AppServer来保证不同用户数据的隔离访问。 对于该种使用方式,使用阿里云账号或者RAM账号提供的密钥来进行签名验证访问。建议您尽量不要直接使用阿里云账号(主账号)的密钥访问OSS,避免出现安全问题。 方式二:使用STS让用户直接访问OSS STS方案描述如下图所示:方案的详细描述如下: App用户登录。App用户和云账号无关,它是App的终端用户,AppServer支持App用户登录。对于每个有效的App用户来说,需要AppServer能定义出每个App用户的最小访问权限。 AppServer请求STS服务获取一个安全令牌(SecurityToken)。在调用STS之前,AppServer需要确定App用户的最小访问权限(用Policy语法描述)以及授权的过期时间。然后通过扮演角色(AssumeRole)来获取一个代表角色身份的安全令牌。 STS返回给AppServer一个有效的访问凭证,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)以及过期时间。 AppServer将访问凭证返回给ClientApp。ClientApp可以缓存这个凭证。当凭证失效时,ClientApp需要向AppServer申请新的有效访问凭证。比如,访问凭证有效期为1小时,那么ClientApp可以每30分钟向AppServer请求更新访问凭证。 ClientApp使用本地缓存的访问凭证去请求Aliyun Service API。云服务会感知STS访问凭证,并会依赖STS服务来验证访问凭证,正确响应用户请求。 RAM和STS授权策略(Policy)配置 对于RAM或者STS授权中使用Policy,详细规则如下。 示例 先看下面的一个Policy示例: { "Version": "1", "Statement": [ { "Action": [ "oss:GetBucketAcl", "oss:ListObjects" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket" ], "Effect": "Allow", "Condition": { "StringEquals": { "acs:UserAgent": "java-sdk", "oss:Prefix": "foo" }, "IpAddress": { "acs:SourceIp": "192.168.0.1" } } }, { "Action": [ "oss:PutObject", "oss:GetObject", "oss:DeleteObject" ], "Resource": [ "acs:oss:*:1775305056529849:mybucket/file*" ], "Effect": "Allow", "Condition": { "IpAddress": { "acs:SourceIp": "192.168.0.1" } } } ] } 这是一个授权的Policy,用户用这样的一个Policy通过RAM或STS服务向其他用户授权。Policy当中有一个Statement(一条Policy当中可以有多条Statement)。Statement里面规定了相应的Action、Resource、Effect和Condition。 这条Policy把用户自己名下的mybucket和mybucket/file*这些资源授权给相应的用户,并且支持GetBucketAcl、GetBucket、PutObject、GetObject和DeleteObject这几种操作。Condition中的条件表示UserAgent为java-sdk,源IP为192.168.0.1的时候鉴权才能通过,被授权的用户才能访问相关的资源。Prefix这个Condition是在GetBucket(ListObjects)的时候起作用的,关于这个字段的解释详见OSS的API文档。 配置细则 Version Version定义了Policy的版本,本文档中sw2q的配置方式,设置为1。 Statement 通过Statement描述授权语义,其中可以根据业务场景包含多条语义,每条包含对Action、Effect、Resource和Condition的描述。每次请求系统会逐条依次匹配检查,所有匹配成功的Statement会根据Effect的设置不同分为通过(Allow)、禁止(Deny),其中禁止(Deny)的优先。如果匹配成功的都为通过,该条请求即鉴权通过。如果匹配成功有一条禁止,或者没有任何条目匹配成功,该条请求被禁止访问。 Action Action分为三大类:Service级别操作,对应的是GetService操作,用来列出所有属于该用户的Bucket列表。 Bucket级别操作,对应类似于oss:PutBucketAcl、oss:GetBucketLocation之类的操作,操作的对象是Bucket,它们的名称和相应的接口名称一一对应。 Object级别操作,分为oss:GetObject、oss:PutObject、oss:DeleteObject和oss:AbortMultipartUpload,操作对象是Object。 如想授权某一类的Object的操作,可以选择这几种的一种或几种。另外,所有的Action前面都必须加上oss:,如上面例子所示。Action是一个列表,可以有多个Action。具体的Action和API接口的对应关系如下: Service级别 API Action GetService(ListBuckets) oss:ListBuckets Bucket级别 API Action PutBucket oss:PutBucket GetBucket(ListObjects) oss:ListObjects PutBucketAcl oss:PutBucketAcl DeleteBucket oss:DeleteBucket GetBucketLocation oss:GetBucketLocation GetBucketAcl oss:GetBucketAcl GetBucketLogging oss:GetBucketLogging PutBucketLogging oss:PutBucketLogging DeleteBucketLogging oss:DeleteBucketLogging GetBucketWebsite oss:GetBucketWebsite PutBucketWebsite oss:PutBucketWebsite DeleteBucketWebsite oss:DeleteBucketWebsite GetBucketReferer oss:GetBucketReferer PutBucketReferer oss:PutBucketReferer GetBucketLifecycle oss:GetBucketLifecycle PutBucketLifecycle oss:PutBucketLifecycle DeleteBucketLifecycle oss:DeleteBucketLifecycle ListMultipartUploads oss:ListMultipartUploads PutBucketCors oss:PutBucketCors GetBucketCors oss:GetBucketCors DeleteBucketCors oss:DeleteBucketCors PutBucketReplication oss:PutBucketReplication GetBucketReplication oss:GetBucketReplication DeleteBucketReplication oss:DeleteBucketReplication GetBucketReplicationLocation oss:GetBucketReplicationLocation GetBucketReplicationProgress oss:GetBucketReplicationProgress Object级别 API Action GetObject oss:GetObject HeadObject oss:GetObject PutObject oss:PutObject PostObject oss:PutObject InitiateMultipartUpload oss:PutObject UploadPart oss:PutObject CompleteMultipart oss:PutObject DeleteObject oss:DeleteObject DeleteMultipartObjects oss:DeleteObject AbortMultipartUpload oss:AbortMultipartUpload ListParts oss:ListParts CopyObject oss:GetObject,oss:PutObject UploadPartCopy oss:GetObject,oss:PutObject AppendObject oss:PutObject GetObjectAcl oss:GetObjectAcl PutObjectAcl oss:PutObjectAcl Resource Resource指代的是OSS上面的某个具体的资源或者某些资源(支持*通配),resource的规则是acs:oss:{region}:{bucket_owner}:{bucket_name}/{object_name}。对于所有Bucket级别的操作来说不需要最后的斜杠和{object_name},即acs:oss:{region}:{bucket_owner}:{bucket_name}。Resource也是一个列表,可以有多个Resource。其中的region字段暂时不做支持,设置为*。 Effect Effect代表本条的Statement的授权的结果,分为Allow和Deny,分别指代通过和禁止。多条Statement同时匹配成功时,禁止(Deny)的优先级更高。 例如,期望禁止用户对某一目录进行删除,但对于其他文件有全部权限: { "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:*" ], "Resource": [ "acs:oss:*:*:bucketname" ] }, { "Effect": "Deny", "Action": [ "oss:DeleteObject" ], "Resource": [ "acs:oss:*:*:bucketname/index/*", ] } ] } Condition Condition代表Policy授权的一些条件,上面的示例里面可以设置对于acs:UserAgent的检查、acs:SourceIp的检查、还有oss:Prefix这项用来在GetBucket的时候对资源进行限制。 OSS支持的Condition如下: condition 功能 合法取值 acs:SourceIp 指定ip网段 普通的ip,支持*通配 acs:UserAgent 指定http useragent头 字符串 acs:CurrentTime 指定合法的访问时间 ISO8601格式 acs:SecureTransport 是否是https协议 “true”或者”false” oss:Prefix 用作ListObjects时的prefix 合法的object name 更多示例 针对具体场景更多的授权策略配置示例,可以参考教程示例:控制存储空间和文件夹的访问权限和OSS授权常见问题。 Policy在线图形化便捷配置工具,请单击这里。 最佳实践 RAM和STS使用指南

2019-12-01 23:12:47 0 浏览量 回答数 0

阿里云高校特惠,助力学生创业梦!0元体验,快速入门云计算!

学生动手场景应用,快速了解并掌握云服务器的各种新奇玩法!

回答

Go 的优势在于能够将简单的和经过验证的想法结合起来,同时避免了其他语言中出现的许多问题。本文概述了 Go 背后的一些设计原则和工程智慧,作者认为,Go 语言具备的所有这些优点,将共同推动其成为接替 Java 并主导下一代大型软件开发平台的最有力的编程语言候选。很多优秀的编程语言只是在个别领域比较强大,如果将所有因素都纳入考虑,没有其他语言能够像 Go 语言一样“全面开花”,在大型软件工程方面,尤为如此。 基于现实经验 Go 是由经验丰富的软件行业老手一手创建的,长期以来,他们对现有语言的各种缺点有过切身体会的痛苦经历。几十年前,Rob Pike 和 Ken Thompson 在 Unix、C 和 Unicode 的发明中起到了重要作用。Robert Griensemer 在为 JavaScript 和 Java 开发 V8 和 HotSpot 虚拟机之后,在编译器和垃圾收集方面拥有数十年的经验。有太多次,他们不得不等待 Google 规模的 C++/Java 代码库进行编译。于是,他们开始着手创建新的编程语言,将他们半个世纪以来的编写代码所学到的一切经验包含进去。 专注于大型工程 小型工程项目几乎可以用任何编程语言来成功构建。当成千上万的开发人员在数十年的持续时间压力下,在包含数千万行代码的大型代码库上进行协作时,就会发生真正令人痛苦的问题。这样会导致一些问题,如下: 较长的编译时间导致中断开发。代码库由几个人 / 团队 / 部门 / 公司所拥有,混合了不同的编程风格。公司雇佣了数千名工程师、架构师、测试人员、运营专家、审计员、实习生等,他们需要了解代码库,但也具备广泛的编码经验。依赖于许多外部库或运行时,其中一些不再以原始形式存在。在代码库的生命周期中,每行代码平均被重写 10 次,被弄得千疮百痍,而且还会发生技术偏差。文档不完整。 Go 注重减轻这些大型工程的难题,有时会以使小型工程变得更麻烦为代价,例如,代码中到处都需要几行额外的代码行。 注重可维护性 Go 强调尽可能多地将工作转给自动化的代码维护工具中。Go 工具链提供了最常用的功能,如格式化代码和导入、查找符号的定义和用法、简单的重构以及代码异味的识别。由于标准化的代码格式和单一的惯用方式,机器生成的代码更改看起来非常接近 Go 中人为生成的更改并使用类似的模式,从而允许人机之间更加无缝地协作。 保持简单明了 初级程序员为简单的问题创建简单的解决方案。高级程序员为复杂的问题创建复杂的解决方案。伟大的程序员找到复杂问题的简单解决方案。 ——Charles Connell 让很多人惊讶的一点是,Go 居然不包含他们喜欢的其他语言的概念。Go 确实是一种非常小巧而简单的语言,只包含正交和经过验证的概念的最小选择。这鼓励开发人员用最少的认知开销来编写尽可能简单的代码,以便许多其他人可以理解并使用它。 使事情清晰明了 良好的代码总是显而易见的,避免了那些小聪明、难以理解的语言特性、诡异的控制流和兜圈子。 许多语言都致力提高编写代码的效率。然而,在其生命周期中,人们阅读代码的时间却远远超过最初编写代码所需的时间(100 倍)。例如,审查、理解、调试、更改、重构或重用代码。在查看代码时,往往只能看到并理解其中的一小部分,通常不会有完整的代码库概述。为了解释这一点,Go 将所有内容都明确出来。 错误处理就是一个例子。让异常在各个点中断代码并在调用链上冒泡会更容易。Go 需要手动处理和返回每个错误。这使得它可以准确地显示代码可以被中断的位置以及如何处理或包装错误。总的来说,这使得错误处理编写起来更加繁琐,但是也更容易理解。 简单易学 Go 是如此的小巧而简单,以至于人们可以在短短几天内就能研究通整个语言及其基本概念。根据我们的经验,培训用不了一个星期(相比于掌握其他语言需要几个月),初学者就能够理解 Go 专家编写的代码,并为之做出贡献。为了方便吸引更多的用户,Go 网站提供了所有必要的教程和深入研究的文章。这些教程在浏览器中运行,允许人们在将 Go 安装到本地计算机上之前就能够学习和使用 Go。 解决之道 Go 强调的是团队之间的合作,而不是个人的自我表达。 在 Go(和 Python)中,所有的语言特性都是相互正交和互补的,通常有一种方法可以做一些事情。如果你想让 10 个 Python 或 Go 程序员来解决同一个问题,你将会得到 10 个相对类似的解决方案。不同的程序员在彼此的代码库中感觉更自在。在查看其他人的代码时,国骂会更少,而且人们的工作可以更好地融合在一起,从而形成了一致的整体,人人都为之感到自豪,并乐于工作。这还避免了大型工程的问题,如: 开发人员认为良好的工作代码很“混乱”,并要求在开始工作之前进行重写,因为他们的思维方式与原作者不同。 不同的团队成员使用不同的语言子集来编写相同代码库的部分内容。 ![image.png](https://ucc.alicdn.com/pic/developer-ecology/e64418f1455d46aaacfdd03fa949f16d.png) 简单、内置的并发性 Go 专为现代多核硬件设计。 目前使用的大多数编程语言(Java、JavaScript、Python、Ruby、C、C++)都是 20 世纪 80 年代到 21 世纪初设计的,当时大多数 CPU 只有一个计算内核。这就是为什么它们本质上是单线程的,并将并行化视为边缘情况的马后炮。通过现成和同步点之类的附加组件来实现,而这些附加组件既麻烦又难以正确使用。第三方库虽然提供了更简单的并发形式,如 Actor 模型,但是总有多个可用选项,结果导致了语言生态系统的碎片化。今天的硬件拥有越来越多的计算内核,软件必须并行化才能高效运行。Go 是在多核处理器时代编写的,并且在语言中内置了简单、高级的 CSP 风格并发性。 面向计算的语言原语 就深层而言,计算机系统接收数据,对其进行处理(通常要经过几个步骤),然后输出结果数据。例如,Web 服务器从客户端接收 HTTP 请求,并将其转换为一系列数据库或后端调用。一旦这些调用返回,它就将接收到的数据转换成 HTML 或 JSON 并将其输出给调用者。Go 的内置语言原语直接支持这种范例: 结构表示数据 读和写代表流式 IO 函数过程数据 goroutines 提供(几乎无限的)并发性 在并行处理步骤之间传输管道数据 因为所有的计算原语都是由语言以直接形式提供的,因此 Go 源代码更直接地表达了服务器执行的操作。 OO — 好的部分 更改基类中的某些内容的副作用 面向对象非常有用。过去几十年来,面向对象的使用富有成效,并让我们了解了它的哪些部分比其他部分能够更好地扩展。Go 在面向对象方面采用了一种全新的方法,并记住了这些知识。它保留了好的部分,如封装、消息传递等。Go 还避免了继承,因为它现在被认为是有害的,并为组合提供了一流的支持。 现代标准库 目前使用的许多编程语言(Java、JavaScript、Python、Ruby)都是在互联网成为当今无处不在的计算平台之前设计的。因此,这些语言的标准库只提供了相对通用的网络支持,而这些网络并没有针对现代互联网进行优化。Go 是十年前创建的,当时互联网已全面发展。Go 的标准库允许在没有第三方库的情况下创建更复杂的网络服务。这就避免了第三方库的常见问题: 碎片化:总是有多个选项实现相同的功能。 膨胀:库常常实现的不仅仅是它们的用途。 依赖地狱:库通常依赖于特定版本的其他库。 未知质量:第三方代码的质量和安全性可能存在问题。 未知支持:第三方库的开发可能随时停止支持。 意外更改:第三方库通常不像标准库那样严格地进行版本控制。 关于这方面更多的信息请参考 Russ Cox 提供的资料 标准化格式 Gofmt 的风格没有人会去喜欢,但人人都会喜欢 gofmt。 ——Rob Pike Gofmt 是一种以标准化方式来格式化 Go 代码的程序。它不是最漂亮的格式化方式,但却是最简单、最不令人生厌的格式化方式。标准化的源代码格式具有惊人的积极影响: 集中讨论重要主题: 它消除了围绕制表符和空格、缩进深度、行长、空行、花括号的位置等一系列争论。 开发人员在彼此的代码库中感觉很自在, 因为其他代码看起来很像他们编写的代码。每个人都喜欢自由地按照自己喜欢的方式进行格式化代码,但如果其他人按照自己喜欢的方式格式化了代码,这么做很招人烦。 自动代码更改并不会打乱手写代码的格式,例如引入了意外的空白更改。 许多其他语言社区现在正在开发类似 gofmt 的东西。当作为第三方解决方案构建时,通常会有几个相互竞争的格式标准。例如,JavaScript 提供了 Prettier 和 StandardJS。这两者都可以用,也可以只使用其中的一个。但许多 JS 项目并没有采用它们,因为这是一个额外的决策。Go 的格式化程序内置于该语言的标准工具链中,因此只有一个标准,每个人都在使用它。 快速编译 ![image.png](https://ucc.alicdn.com/pic/developer-ecology/8a76f3f07f484266af42781d9e7b8692.png) 对于大型代码库来说,它们长时间的编译是促使 Go 诞生的原因。Google 主要使用的是 C++ 和 Java,与 Haskell、Scala 或 Rust 等更复杂的语言相比,它们的编译速度相对较快。尽管如此,当编译大型代码库时,即使是少量的缓慢也会加剧编译的延迟,从而激怒开发人员,并干扰流程。Go 的设计初衷是为了提高编译效率,因此它的编译器速度非常快,几乎没有编译延迟的现象。这给 Go 开发人员提供了与脚本类语言类似的即时反馈,还有静态类型检查的额外好处。 交叉编译 由于语言运行时非常简单,因此它被移植到许多平台,如 macOS、Linux、Windows、BSD、ARM 等。Go 可以开箱即用地为所有这些平台编译二进制文件。这使得从一台机器进行部署变得很容易。 快速执行 Go 的运行速度接近于 C。与 JITed 语言(Java、JavaScript、Python 等)不同,Go 二进制文件不需要启动或预热的时间,因为它们是作为编译和完全优化的本地代码的形式发布的。Go 的垃圾收集器仅引入微秒量级的可忽略的停顿。除了快速的单核性能外,Go 还可以轻松利用所有的 CPU 内核。 内存占用小 像 JVM、Python 或 Node 这样的运行时不仅仅在运行时加载程序代码,每次运行程序时,它们还会加载大型且高度复杂的基础架构,以进行编译和优化程序。如此一来,它们的启动时间就变慢了,并且还占用了大量内存(数百兆字节)。而 Go 进程的开销更小,因为它们已经完全编译和优化,只需运行即可。Go 还以非常节省内存的方式来存储数据。在内存有限且昂贵的云环境中,以及在开发过程中,这一点非常重要。我们希望在一台机器上能够快速启动整个堆栈,同时将内存留给其他软件。 部署规模小 Go 的二进制文件大小非常简洁。Go 应用程序的 Docker 镜像通常比用 Java 或 Node 编写的等效镜像要小 10 倍,这是因为它无需包含编译器、JIT,以及更少的运行时基础架构的原因。这些特点,在部署大型应用程序时很重要。想象一下,如果要将一个简单的应用程序部署到 100 个生产服务器上会怎么样?如果使用 Node/JVM 时,我们的 Docker 注册表就必须提供 100 个 docker 镜像,每个镜像 200MB,那么一共就需要 20GB。要完成这些部署就需要一些时间。想象一下,如果我们想每天部署 100 次的话,如果使用 Go 服务,那么 Docker 注册表只需提供 10 个 docker 镜像,每个镜像只有 20MB,共只需 2GB 即可。大型 Go 应用程序可以更快、更频繁地部署,从而使得重要更新能够更快地部署到生产环境中。 独立部署 Go 应用程序部署为一个包含所有依赖项的单个可执行文件,并无需安装特定版本的 JVM、Node 或 Python 运行时;也不必将库下载到生产服务器上,更无须对运行 Go 二进制文件的机器进行任何更改。甚至也不需要讲 Go 二进制文件包装到 Docker 来共享他们。你需要做的是,只是将 Go 二进制文件放到服务器上,它就会在那里运行,而不用关心服务器运行的是什么。前面所提到的那些,唯一的例外是使用net和os/user包时针对对glibc的动态链接。 供应依赖关系 Go 有意识避免使用第三方库的中央存储库。Go 应用程序直接链接到相应的 Git 存储库,并将所有相关代码下载(供应)到自己的代码库中。这样做有很多好处: 在使用第三方代码之前,我们可以对其进行审查、分析和测试。该代码就和我们自己的代码一样,是我们应用程序的一部分,应该遵循相同的质量、安全性和可靠性标准。 无需永久访问存储依赖项的各个位置。从任何地方(包括私有 Git repos)获取第三方库,你就能永久拥有它们。 经过验收后,编译代码库无需进一步下载依赖项。 若互联网某处的代码存储库突然提供不同的代码,这也并不足为奇。 即使软件包存储库速度变慢,或托管包不复存在,部署也不会因此中断。 兼容性保证 Go 团队承诺现有的程序将会继续适用于新一代语言。这使得将大型项目升级到最新版本的编译器会非常容易,并且可从它们带来的许多性能和安全性改进中获益。同时,由于 Go 二进制文件包含了它们需要的所有依赖项,因此可以在同一服务器上并行运行使用不同版本的 Go 编译器编译的二进制文件,而无需进行复杂的多个版本的运行时设置或虚拟化。 文档 在大型工程中,文档对于使软件可访问性和可维护性非常重要。与其他特性类似,Go 中的文档简单实用: 由于它是嵌入到源代码中的,因此两者可以同时维护。 它不需要特殊的语法,文档只是普通的源代码注释。 可运行单元测试通常是最好的文档形式。因此 Go 要求将它们嵌入到文档中。 所有的文档实用程序都内置在工具链中,因此每个人都使用它们。 Go linter 需要导出元素的文档,以防止“文档债务”的积累。 商业支持的开源 当商业实体在开放式环境下开发时,那么一些最流行的、经过彻底设计的软件就会出现。这种设置结合了商业软件开发的优势——一致性和精细化,使系统更为健壮、可靠、高效,并具有开放式开发的优势,如来自许多行业的广泛支持,多个大型实体和许多用户的支持,以及即使商业支持停止的长期支持。Go 就是这样发展起来的。 缺点 当然,Go 也并非完美无缺,每种技术选择都是有利有弊。在决定选择 Go 之前,有几个方面需要进行考虑考虑。 未成熟 虽然 Go 的标准库在支持许多新概念(如 HTTP 2 Server push 等)方面处于行业领先地位,但与 JVM 生态系统中的第三方库相比,用于外部 API 的第三方 Go 库可能不那么成熟。 即将到来的改进 由于清楚几乎不可能改变现有的语言元素,Go 团队非常谨慎,只在新特性完全开发出来后才添加新特性。在经历了 10 年的有意稳定阶段之后,Go 团队正在谋划对语言进行一系列更大的改进,作为 Go 2.0 之旅的一部分。 无硬实时 虽然 Go 的垃圾收集器只引入了非常短暂的停顿,但支持硬实时需要没有垃圾收集的技术,例如 Rust。 结语 本文详细介绍了 Go 语言的一些优秀的设计准则,虽然有的准则的好处平常看起来没有那么明显。但当代码库和团队规模增长几个数量级时,这些准则可能会使大型工程项目免于许多痛苦。总的来说,正是这些设计准则让 Go 语言成为了除 Java 之外的编程语言里,用于大型软件开发项目的绝佳选择。

有只黑白猫 2020-01-07 14:11:38 0 浏览量 回答数 0

问题

MaxCompute百问集锦(持续更新20171011)

隐林 2019-12-01 20:19:23 38430 浏览量 回答数 18
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板