精华内容
下载资源
问答
  • 关于session和token的使用,网上争议一直很大。总的来说争议在这里:session是空间换时间,而token是时间换空间。session占用空间,但是可以管理过期时间,token管理部了过期时间,但是不占用空间.sessionId失效问题...

    关于session和token的使用,网上争议一直很大。

    总的来说争议在这里:

    session是空间换时间,而token是时间换空间。session占用空间,但是可以管理过期时间,token管理部了过期时间,但是不占用空间.

    sessionId失效问题和token内包含。

    session基于cookie,app请求并没有cookie 。

    token更加安全(每次请求都需要带上)。

    开始正文了...

    本文大概流程:

    oauth2流程简介

    我在这里只介绍常用的密码授权。

    Oauth2 密码授权流程

    在oauth2协议里,每一个应用都有自己的一个clientId和clientSecret(需要去认证方申请),所以一旦想通过认证,必须要有认证方下发的clientId和secret。

    原理这块确实很麻烦,希望不理解的多看看参考文档。

    1. pom

    org.springframework.boot

    spring-boot-starter-security

    org.springframework.security.oauth

    spring-security-oauth2

    2. 项目架构介绍

    我们需要这七个类来完成。

    3. UserDetail实现认证第一步

    MyUserDetailsService.java

    /**

    * Created by Fant.J.

    */

    @Component

    public class MyUserDetailsService implements UserDetailsService {

    @Reference(version = "2.0.0")

    private UserService userService;

    @Override

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    String passwd = "";

    System.out.println("收到的账号"+username);

    if (CheckFormat.isEmail(username)){

    passwd = userService.selectPasswdByEmail(username);

    }else if (CheckFormat.isPhone(username)){

    passwd = userService.selectPasswdByPhone(username);

    }else {

    throw new RuntimeException("登录账号不存在");

    }

    System.out.println("查到的密码"+passwd);

    return new User(username, passwd, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));

    }

    }

    这里重写了security认证UserDetailsService 的接口方法,添加了自定义数据库密码的查询和校验。

    为什么我把它放在了controller包了呢,因为我用的dubbo,@Reference注解扫描包是controller。这注解在别的包下失效。没搞过dubbo的朋友就把它当作是调用service层就行。

    4. 认证成功/失败处理器

    这部分在security的整合(一)就有,这里稍有改动。

    改动一:去掉了返回view还是json的判断,统一返回json。

    改动二:修改登陆成功处理器,添加oauth2 客户端的认证。

    MyAuthenticationFailHandler.java

    /**

    * 自定义登录失败处理器

    * Created by Fant.J.

    */

    @Component

    public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override

    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

    logger.info("登录失败");

    //设置状态码

    response.setStatus(500);

    response.setContentType("application/json;charset=UTF-8");

    //将 登录失败 信息打包成json格式返回

    response.getWriter().write(JSON.toJSONString(ServerResponse.createByErrorMessage(exception.getMessage())));

    }

    }

    MyAuthenticationSuccessHandler.java

    /**

    * Created by Fant.J.

    */

    @Component

    public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired

    private ClientDetailsService clientDetailsService;

    @Autowired

    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Override

    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

    logger.info("登录成功");

    String header = request.getHeader("Authorization");

    if (header == null && !header.startsWith("Basic")) {

    throw new UnapprovedClientAuthenticationException("请求投中无client信息");

    }

    String[] tokens = this.extractAndDecodeHeader(header, request);

    assert tokens.length == 2;

    //获取clientId 和 clientSecret

    String clientId = tokens[0];

    String clientSecret = tokens[1];

    //获取 ClientDetails

    ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

    if (clientDetails == null){

    throw new UnapprovedClientAuthenticationException("clientId 不存在"+clientId);

    //判断 方言 是否一致

    }else if (!StringUtils.equals(clientDetails.getClientSecret(),clientSecret)){

    throw new UnapprovedClientAuthenticationException("clientSecret 不匹配"+clientId);

    }

    //密码授权 模式, 组建 authentication

    TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP,clientId,clientDetails.getScope(),"password");

    OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);

    OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request,authentication);

    OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

    //判断是json 格式返回 还是 view 格式返回

    //将 authention 信息打包成json格式返回

    response.setContentType("application/json;charset=UTF-8");

    response.getWriter().write(JSON.toJSONString(ServerResponse.createBySuccess(token)));

    }

    /**

    * 解码请求头

    */

    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) throws IOException {

    byte[] base64Token = header.substring(6).getBytes("UTF-8");

    byte[] decoded;

    try {

    decoded = Base64.decode(base64Token);

    } catch (IllegalArgumentException var7) {

    throw new BadCredentialsException("Failed to decode basic authentication token");

    }

    String token = new String(decoded, "UTF-8");

    int delim = token.indexOf(":");

    if (delim == -1) {

    throw new BadCredentialsException("Invalid basic authentication token");

    } else {

    return new String[]{token.substring(0, delim), token.substring(delim + 1)};

    }

    }

    }

    描述:

    从request的请求头中拿到Authorization信息,根据clientId获取到secret和请求头中的secret信息做对比,如果正确,组建一个新的TokenRequest类,然后根据前者和clientDetails创建OAuth2Request对象,然后根据前者和authentication创建OAuth2Authentication对象。最后通过AuthorizationServerTokenServices和前者前者创建OAuth2AccessToken对象。然后将token返回。

    提示:

    密码授权,我们在请求token的时候,需要一个包含clientid和clientSecret的请求头还有三个参数。

    请求头:Authorization -> Basic aW50ZXJuZXRfcGx1czppbnRlcm5ldF9wbHVz 。注意是Basic 开头然后是clientid:clientScret 格式进行base64加密后的字符串。

    请求参数:username和password是必须要的参数,值对应的就是账号密码,还有给可有可无的就是scope,它来声明该用户有多大的权限,默认是all。grant_type也是默认的参数,默认是password,它表示你以哪种认证模式来认证。

    这是请求头解密现场

    5. 配置认证/资源服务器

    MyResourceServerConfig.java

    /**

    * 资源服务器

    * Created by Fant.J.

    */

    @Configuration

    @EnableResourceServer

    public class MyResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired

    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Autowired

    private MyAuthenticationFailHandler myAuthenticationFailHandler;

    @Override

    public void configure(HttpSecurity http) throws Exception {

    //表单登录 方式

    http.formLogin()

    .loginPage("/authentication/require")

    //登录需要经过的url请求

    .loginProcessingUrl("/authentication/form")

    .successHandler(myAuthenticationSuccessHandler)

    .failureHandler(myAuthenticationFailHandler);

    http

    .authorizeRequests()

    .antMatchers("/user/*")

    .authenticated()

    .antMatchers("/oauth/token").permitAll()

    .anyRequest()

    .permitAll()

    .and()

    //关闭跨站请求防护

    .csrf().disable();

    }

    }

    我这里只需要认证/user/*开头的url。@EnableResourceServer这个注解就决定了这十个资源服务器。它决定了哪些资源需要什么样的权限。

    MyAuthorizationServerConfig.java

    /**

    * 认证服务器

    * Created by Fant.J.

    */

    @Configuration

    @EnableAuthorizationServer

    public class MyAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired

    private AuthenticationManager authenticationManager;

    @Autowired

    private UserDetailsService userDetailsService;

    @Override

    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {

    super.configure(security);

    }

    /**

    * 客户端配置(给谁发令牌)

    * @param clients

    * @throws Exception

    */

    @Override

    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

    clients.inMemory().withClient("internet_plus")

    .secret("internet_plus")

    //有效时间 2小时

    .accessTokenValiditySeconds(72000)

    //密码授权模式和刷新令牌

    .authorizedGrantTypes({"refresh_token","password"})

    .scopes( "all");

    }

    @Override

    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

    endpoints

    .authenticationManager(authenticationManager)

    .userDetailsService(userDetailsService);

    }

    }

    }

    @EnableAuthorizationServer就代表了它是个认证服务端。

    一般来讲,认证服务器是第三方提供的服务,比如你想接入qq登陆接口,那么认证服务器就是腾讯提供,然后你在本地做资源服务,但是认证和资源服务不是非要物理上的分离,只需要做到逻辑上的分离就好。

    认证服务中,我们获取到ClientDetailsServiceConfigurer 并设置clientId和secret还有令牌有效期,还有支持的授权模式,还有用户权限范围。

    执行

    好了,启动项目。

    1. 给/oauth/token 发送post请求获取token

    请求头:Authorization:Basic +clientid:secret 的base64加密字符串 (认证服务器中设置的client信息)

    请求参数:username password (用户登陆账号密码)

    {

    "data": {

    "refreshToken": {

    "expiration": 1528892642111,

    "value": "xxxxxx-xxxxxx-xxxxx-xxxxxxxx"

    },

    "scope": [

    "all"

    ],

    "tokenType": "bearer",

    "value": "xxxxxx-xxxxxx-xxxxx-xxxxxxxx"

    },

    "status": 200,

    "success": true

    }

    2. 给/oauth/token 发送post请求刷新token

    请求头: 不需要

    请求参数:

    grant_type:refresh_token

    refresh_token:获取token时返回的refreshToken的value

    3. 访问受保护的资源,比如/user/2

    类型:get请求

    请求头:Authorization: bearer + tokenValue

    介绍下我的所有文集:

    流行框架

    底层实现原理:

    展开全文
  • 之后查的资料,按照这个上面的教程配置,但是最后运行得到的device token还是空值,我真是无语了,困惑了好久了这个问题,http://dev.umeng.com/push/android/integration#1_8 ,
  • 授权服务在授权服务里,用户通过用户名密码,或者手机和验证码等方式登陆之后,在http头里会有授权的标识,在客户端调用时,需要添加当时有效的token才可以正常访问被授权的页面。Content-Type:application/...

    在微服务架构里,服务与服务之间的调用一般用feign就可以实现,它是一种可视化的rpc,并且集成了ribbon的负载均衡能力,所以很受欢迎。

    授权服务

    在授权服务里,用户通过用户名密码,或者手机和验证码等方式登陆之后,在http头里会有授权的标识,在客户端调用时,需要添加当时有效的token才可以正常访问被授权的页面。

    Content-Type:application/json

    Authorization:Bearer d79c064c-8675-4047-a119-fac692e447e8

    而在业务层里,服务与服务之间使用feign来实现调用,而授权的代码我们可以通过拦截器实现,在feign请求之前,把当前服务的token添加到目标服务的请求头就可以了,一般是这样实现的。

    /**

    * 发送FeignClient设置Header信息.

    * http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/

    * Hystrix传播ThreadLocal对象

    */

    @Component

    public class TokenFeignClientInterceptor implements RequestInterceptor {

    /**

    * token放在请求头.

    *

    * @param requestTemplate 请求参数

    */

    @Override

    public void apply(RequestTemplate requestTemplate) {

    RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();

    if (requestAttributes != null) {

    HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

    String token = request.getHeader(TokenContext.KEY_OAUTH2_TOKEN);

    requestTemplate.header(TokenContext.KEY_OAUTH2_TOKEN,

    new String[] {token});

    }

    }

    }

    上面的拦截器代码没有什么问题,也很好理解,但事实上,当你的feign开启了hystrix功能,如果开启了,需要把hystrix的策略进行修改,默认是THREAD的,这个级别时ThreadLocal是空的,所以你的授权不能传给feign的拦截器.

    hystrix.command.default.execution.isolation.strategy: SEMAPHORE

    资源项目里获取当前用户

    在另一个项目,需要其它获取当前用户,需要使用下面的代码。

    先配置一个授权的地址

    security:

    oauth2:

    resource:

    id: user

    user-info-uri: http://${auth.host:localhost}:${auth.port:8002}/user # 这里是授权服务的地址,即auth-service

    prefer-token-info: false

    auth:

    host: localhost #这个不可以用eureka里的服务名,只能使用docker-compose里的服务名

    port: 8002

    下面的代码用来获取当前用户

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    String user = objectMapper.writeValueAsString(authentication.getPrincipal());

    本讲主要对feign的请求头传递信息进行讲解,开发时遇到的坑总节了一下,分享给大家!

    展开全文
  • "implicit", "responseType": "token", "attributes": {} } 3.2 固定规则部分 上面是各种不同AuthorizationGrantType下的OAuth2AuthorizationRequest的成员变量个性化取值策略, 还有几个参数的规则是固定的: ...

    392c772495dc6d0f7c919c7ab565dec6.png

    1. 前言

    在之前文章中我们找到了拦截 OAuth2 授权请求入口/oauth2/authorization的过滤器OAuth2AuthorizationRequestRedirectFilter,并找到了真正发起 OAuth2 授权请求的方法sendRedirectForAuthorization。但是这个方法并没有细说,所以今天接着上一篇把这个坑给补上。

    2. sendRedirectForAuthorization

    这个sendRedirectForAuthorization方法没多少代码,它的主要作用就是向第三方平台进行授权重定向访问。它所有的逻辑都和OAuth2AuthorizationRequest有关,因此我们对OAuth2AuthorizationRequest进行轻描淡写是不行的,我们必须掌握OAuth2AuthorizationRequest是怎么来的,干嘛用的。

    OAuth2AuthorizationRequestResolver

    这就需要去分析解析类OAuth2AuthorizationRequestResolver,其核心方法有两个重载,这里分析一个就够了。

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
        // registrationId是通过uri路径参数/oauth2/authorization/{registrationId}获得的
       String registrationId = this.resolveRegistrationId(request);
        // 然后去请求对象request中提取key为action的参数,默认值是login
       String redirectUriAction = getAction(request, "login");
        // 然后进入根本的解析方法
       return resolve(request, registrationId, redirectUriAction);
    }

    上面方法里面的resolve(request, registrationId, redirectUriAction)方法才是最终从/oauth2/authorization提取OAuth2AuthorizationRequest的根本方法。代码太多但是我尽量通俗易懂的来进行图解。resolve方法会根据不同的授权方式(AuthorizationGrantType)来组装不同的OAuth2AuthorizationRequest

    3. OAuth2AuthorizationRequest

    接下来就是 OAuth2.0 协议的核心重中之重了,可能以后你定制化的参考就来自这里,这时圈起来要考的知识点。我会对OAuth2AuthorizationRequestResolver在各种授权方式下的OAuth2AuthorizationRequest对象的解析进行一个完全的总结归纳。大致分为以下两部分:

    3.1 由 AuthorizationGrantType 决定的

    在不同AuthorizationGrantType下对OAuth2AuthorizationRequest的梳理。涉及到的成员变量有:

    • authorizationGrantType ,来自配置spring.security.client.registration.{registrationId}.authorizationGrantType
    • responseType , 由authorizationGrantType 的值决定,参考下面的 JSON。
    • additionalParameters,当authorizationGrantType值为authorization_code时需要额外的一些参数,参考下面 JSON 。
    • attributes,不同的authorizationGrantType存在不同的属性。
    其中类似{registrationId} 的形式表示{registrationId}是一个变量,例如 registrationId=gitee

    在 OAuth2 客户端配置spring.security.client.registration.{registrationId}的前缀中有以下五种情况。

    scope 不包含openid而且client-authentication-method不为none时上述四个参数:

    {
      "authorizationGrantType": "authorization_code",
      "responseType": "code",
      "additionalParameters": {},
      "attributes": {
        "registration_id": "{registrationId}"
      }
    }

    scope 包含openid而且client-authentication-method不为none时上述四个参数:

    {
      "authorizationGrantType": "authorization_code",
      "responseType": "code",
      "additionalParameters": {
        "nonce": "{nonce}的Hash值"
      },
      "attributes": {
        "registration_id": "{registrationId}",
        "nonce": "{nonce}"
      }
    }

    scope不包含openid而且client-authentication-methodnone时上述四个参数:

    {
      "authorizationGrantType": "authorization_code",
      "responseType": "code",
      "additionalParameters": {
        "code_challenge": "{codeVerifier}的Hash值",
        // code_challenge_method 当不是SHA256可能没有该key
        "code_challenge_method": "S256(如果是SHA256算法的话)"
      },
      "attributes": {
        "registration_id": "{registrationId}",
        "code_verifier": "Base64生成的安全{codeVerifier}"
      }
    }

    scope包含openid而且client-authentication-methodnone时上述四个参数:

    {
      "authorizationGrantType": "authorization_code",
      "responseType": "code",
      "additionalParameters": {
        "code_challenge": "{codeVerifier}的Hash值",
        // code_challenge_method 当不是SHA256可能没有该key
        "code_challenge_method": "S256(如果是SHA256算法的话)",
        "nonce": "{nonce}的Hash值"
      },
      "attributes": {
        "registration_id": "{registrationId}",
        "code_verifier": "Base64生成的安全{codeVerifier}",
        "nonce": "{nonce}"
      }
    }

    implicit下要简单的多:

    {
      "authorizationGrantType": "implicit",
      "responseType": "token",
      "attributes": {}
    }

    3.2 固定规则部分

    上面是各种不同AuthorizationGrantType下的OAuth2AuthorizationRequest的成员变量个性化取值策略, 还有几个参数的规则是固定的:

    • clientId 来自于配置,是第三方平台给予我们的唯一标识。
    • authorizationUri来自于配置,用来构造向第三方发起的请求 URL。
    • scopes 来自于配置,是第三方平台给我们授权划定的作用域,可以理解为角色。
    • state 自动生成的,为了防止 csrf 攻击。
    • authorizationRequestUri 向第三方平台发起授权请求的,可以直接通过OAuth2AuthorizationRequest的构建类来设置或者通过上面的authorizationUri等参数来生成,稍后会把构造机制分析一波
    • redirectUriOAuth2AuthorizationRequest被第三方平台收到后,第三方平台会回调这个 URI 来对授权请求进行相应,稍后也会来分析其机制。

    authorizationRequestUri 的构建机制

    如果不显式提供authorizationRequestUri就会通过OAuth2AuthorizationRequest中的

    • responseType
    • clientId
    • scopes
    • state
    • redirectUri
    • additionalParameters

    按照下面的规则进行拼接成authorizationUri的参数串,参数串的keyvalue都要进行 URI 编码。

    authorizationUri?response_type={responseType.getValue()}&client_id={clientId}&scope={scopes元素一个字符间隔}&state={state}&redirect_uri={redirectUri}&{additionalParameter展开进行同样规则的KV参数串}

    然后OAuth2AuthorizationRequestRedirectFilter负责重定向到authorizationRequestUri向第三方请求授权。

    redirectUri

    第三方收到响应会调用redirectUri,回调也是有一定规则的,遵循{baseUrl}/{action}/oauth2/code/{registrationId}的路径参数规则。

    • baseUrl 是从我们/oauth2/authorization请求中提取的基础请求路径。
    • action,有两种默认值loginauthorize ,当/oauth2/authorization请求中包含了action参数时会根据action的值进行填充。
    • registrationId 这个就不用多说了。

    4. 总结

    通过对OAuth2AuthorizationRequest请求对象的规则进行详细分析,我们应该能大致的知道的过滤器OAuth2AuthorizationRequestRedirectFilter流程:

    1. 通过客户端配置构建ClientRegistration,后续可以进行持久化。
    2. 拦截/oauth2/authorization请求并构造OAuth2AuthorizationRequest,然后重定向到authorizationRequestUri进行请求授权。
    3. 第三方通过redirect_uri进行相应。

    那么 Spring Security OAuth2 如何对第三方的回调相应进行处理呢?


    原作者:码农小胖哥
    原文链接:Spring Security 实战干货:OAuth2授权请求是如何构建并执行的
    原出处:公众号
    侵删

    2a8cd008993c53c7d7f896ddd42ebed4.gif
    展开全文
  • 帐号不能为空 (╯‵□′)╯︵┻━┻: 帐号不能为空 不知道怎么解决,可能是获取token的网页发生了变化?命令行下输入的email地址无法返回给响应位置了?</p><p>该提问来源于开源项目:...
  • [img=https://img-bbs.csdn.net/upload/201810/31/1540965716_306617.jpg][/img]
  • 去年,他还在忙着到处做区块链普及和布道工作,而今年的舆论领域已鲜少见到他的身影,因为,他正在着重打造Token Fund领域里的管理规范,希望能成为行业规范的标杆。本文,他向耳朵财经分享了他的行业认知:1、...
        

    编者按:许超逸是BKFUND创始管理合伙人、Hashgard创始人,拥有多年VC股权投资经验。去年,他还在忙着到处做区块链普及和布道工作,而今年的舆论领域已鲜少见到他的身影,因为,他正在着重打造Token Fund领域里的管理规范,希望能成为行业规范的标杆。

    本文,他向耳朵财经分享了他的行业认知:1、区块链认知三阶段; 2、从认识比特币到早期企业融资工具;3、关于投资Token的基金管理领域现在仍是空白,这为BKFUND带来行业的新机会。

    640?wx_fmt=jpeg

    作者  阿多 | 编辑 葭明

    1

    区块链认知三个阶段

    多年来从事VC投资工作的许超逸一直保持着对各行业最新进展的关注,并通过定期撰写研究报告与心得体会来训练行业敏感度。从人工智能、无人驾驶、ARVR到新能源,许超逸始终关注着最前沿的行业。

    最开始了解的时候,许超逸以为区块链不过是一种互联网行业的一个细分领域。直到2016年5月,接触到区块链概念,随着认知的深入,许超逸发现区块链可能远远超出他原本的想象,由此,他总结出区块链认知三阶段:

    阶段一:技术论层面

    最开始大部分人可能都是从技术角度去认识区块链,这源于区块链中密码学的基因,一个个不可篡改的区块使之成为一种分布式记账方式,这是最浅的一种认知。

    阶段二:方法论层面

    区块链作为一种可以连接许多行业的方法论存在,实际上是有落地场景和意义的。

    那么从这个角度看,区块链会改造和颠覆很多行业。在未来,很多行业可能不会以公司的形式存在,可能转变为社群运营的一种开放式商业生态。在这个社区里面,每个人都去做贡献,同时每个人也都能够获得这个生态系统给予的Token作为奖励。

    阶段三:价值观层面

    从价值观层面去思考,区块链实际上代表着一种自由、平等、开放的极客精神,用16个字来总结就是人人参与人人贡献人人获益分享共享这个观念与互联网的观念是有所不同的。

    许超逸认为,互联网世界里的共享经济理念是,如果你把你的东西给我,那么我就把我的也给你,其本质仍然是一种精致的利己主义。但区块链世界强调的是一种更为主动、无私的分享经济,即我先把我的给你,不管你给不给我。所以大家会看到,区块链提倡开源,做出来了一个好的项目,把源代码都免费的给所有人看,让大家在这个基础之上去不断的改进和优化。

    在传统行业里,有个好想法就赶快去申请专利,生怕别人模仿、抄袭,这样的结果是导致大家都在做重复造轮子的工作,浪费了大量的资源。而区块链是一种真正的利他主义精神,在这种核心价值观的指引下,在未来,区块链的体量可能会比互联网大好几个数量级,并且会用2~3年的时间走完互联网20~30年的路

    未来,区块链会像今天的互联网一样,是一个无处不在、无人不用的状况。如果用一句话来定义“区块链是什么”,恐怕是人类有史以来最伟大的发明之一,它通过去中心化的记账网络,保证了每个人的财产、信息、数据神圣不可侵犯。

    2

    从认识比特币到早期企业融资工具

    许超逸对区块链的认知不是一蹴而就的。他实践之路的开端也和大多数人一样:买比特币。“最开始我也是一个韭菜心态”,许超逸说,“但这些币的涨跌幅度很大,变化很快,如果没有长期专业的看盘训练,其实是很难赚到钱的”。

    区块链的应用除了炒币,依然大有可为。许超逸已经认识到,区块链技术可能会对很多行业产生一定的改进作用。从2017年上半年开始,许超逸结合自己的VC经验关注起一些爱西欧的项目。

    那个时候他意识到区块链市场的估值体系与传统VC是不同的,“我们做VC的时候对标的是这个公司上市之后情况,包括行业市场规模、年度的净利润等,然后倒推现阶段的用户规模和增长状态等等。但是这种战略先行的思维在区块链行业是很难做投资的。”这也解释了2018年初投资机构陷入焦虑的一种现状——之前项目方追着投资人跑,现在投资人向项目方要额度,打币慢了,sorry,额度满了。

    爱西欧好像可以成为初创企业的一种融资形式。”这是许超逸作为投资业内人士的一个直观感受。当然,许超逸还是有一些疑问,爱西欧好像跟众筹比较像,众筹分为产品众筹和股权众筹。那么爱西欧到底筹的是什么呢?带着这些疑问,许超逸更加深入地去研究Token的本质。

    爱西欧项目在2017年9月之前如火如荼地进行,一时间优质币、空气币满天飞,这样鱼龙混杂的状况令许超逸也感到忧虑。“爱西欧初衷是好的,但没有规则不成方圆,让骗子项目钻了空子,容易一颗老鼠屎坏一锅汤。”市场甚嚣尘上,等来的是2017年9月4号的监管政策“一刀切”。


    3

    Token Fund领域的管理规范现在是空白

    2017年下半年,经朋友引荐,许超逸正式加入分布式资本担任战略管理部总监。当时全球范围内,已经成立了一些数字资产基金。“Token Fund的投资流程整体很快,因为只要有一个钱包地址作为账号,全世界的LP都可以成为优质项目的新的投资人。”数字资产基金有可能是未来资金的另一种新的形式,由分布式资本孵化的BKFUND在这样的背景下应运而生。

    “BKFUND基金规模不大,主要的投资人在数字资产领域有丰富投资经验。他们相信我们的判断能力,把钱交给我们来进行投资。所以这支基金没有面向公众,只是在非常小的范围内做一些有益的探索。”

    当问到BKFUND如何挑选优质投资标的的时候,许超逸告诉耳朵财经记者他的五条判断标准

    “第一是看人,包括创始人的价值观、格局、心态,是捞快钱还是为行业做出一些贡献,行业内不乏一些蛀虫和毒瘤,但这些一定是做不长久的;

    第二是看团队的背景、知识积累是与所做事情的方向是不是相吻合;

    第三是看项目本身,靠谱的项目一定是逻辑自洽的,在原来的行业生态中的商业闭环是怎样的,在区块链去中心化的场景中到底能不能提升效率、降低成本,这些都是需要考虑的;

    第四是同领域竞品的横向研究和比较,它的战略壁垒是需要分析的;

    第五是估值要与项目所处阶段相匹配,包括团队的背景和后续研发能力,以及这个项目从推出到落地所需要的资金量的匹配。”

    在挑选项目的过程中,许超逸及其团队也意识到,数字资产基金与之前的VC股权基金、证券投资基金完全不一样。

    “首先,VC的股权基金有一整套的协议模板,节奏相应地比较慢,推出之后才会有退出的收益。其次,证券投资基金有一个比较集中式的清算机构,不用自己去计算价格。但是在Token Fund领域,有很多的交易所和钱包,还有一大堆的币种,这样管理起来就非常的复杂。”

    做多年技术和管理的许超逸对规范有着一种天然的敏锐,“业界没有规范,我们就自己做规范。以一个小规模的形式,把业界的标杆打造出来。”这是许超逸、也是BKFUND的初心。

    BKFUND团队在寻找投资标的过程中逐步积累、优化,建立起第一个Token Fund领域的管理规范,包括资产如何管理、钱包如何管理、账号如何管理、投资的风控如何把控、投资收益如何测算、数字资产的会计计量、如何向投资者做信息披露等等。“四个月的时间里,我们总结了Token Fund投资中可能出现的各种问题,用实际的投资案例去完善,最终输出了一个比较系统化的规范。通过这套规范流程,我们能够优化资产分配,多维度地判断投资风险,并且实时地掌握资产的动态状况。基金管理效率大大提高,减少出错概率。”

    “我们是希望把自己的内功先打好,然后再对外输出经验,赋能他人。”抱着对行业有所促进的想法,许超逸告诉耳朵财经,在未来,BKFUND将开源这套管理规范,并试图打造成一个业界标准化的基金管理规范化指引(SOP),来帮助Token Fund基金管理人员去更好地管理基金,同时BKFUND还将发起一个被称之为“分布式的可信资产管理协议”Hashgard项目,作为数字资产管理行业的基础设施,提升行业服务效率,降低基金管理与合规的成本,并且将最大程度保护投资人的权益。

    许超逸去年还在不断做区块链的普及和布道,现在成为BKFUND创始管理合伙人、Hashgard创始人的他已经没空讲了。唯有埋头做事,最后趋势会告诉迟疑拥抱区块链的人们到底错过了什么。而对于BKFUND的定位,许超逸在采访的最后告诉耳朵财经:“BKFUND的定位就是业界有态度、有原则的一支基金,我们绝不去投资那些让这个行业泡沫增大的项目,也希望为行业树立一个规范化的标杆,从源头去减少代投跑路、损害普通投资者利益的事情发生。”

    我是本文作者阿多,

    交流、爆料可以加微信yuduo1990,

    劳请备注姓名、公司和职位。

    加耳朵君进社群

    玩转区块链

    640?wx_fmt=jpeg

    往期推荐

    (点击图片浏览)

    640?wx_fmt=jpeg

    640?wx_fmt=jpeg

    640?wx_fmt=jpeg

    关注我们在底部菜单栏可获得379份区块链项目白皮书

    更多消息请加客服进群交流:jf515292

    640?wx_fmt=png


    聆听区块链的声音

    --- 耳朵财经 ---

    ---- end ----

    640?wx_fmt=jpeg

    关注我们你会领先世界99%的人了解区块链

    展开全文
  • 1.在springboot中解决跨域的问题,用...2.但在整合到springsecurity的时候,发现token失效或为空获取不到返回的状态码问题,是因为springsecurity的配置也要允许跨域访问,springsecurity配置类里加上.cors()即可
  • Ifcc token

    2020-12-26 12:58:05
    <div><h3>确保 Token Profile 的顺利通过,务必逐一确保以下检查项并补充项目资料: <p><strong>.json 及 .png 文件检查项 - [x] logo 尺寸:120*120 px - [x] logo 背景:透明 - [x] ...
  • token令牌应用

    2020-06-15 10:19:08
    前端提交code码 后端通过文件配置获取app_id app_secret login_url 向微信服务器发送请求 这里可能返回值为空字符串 并不是错误 将值转化为数组判断信息 将获取到的openid session_key 以及用户枚举权限 通过tp5.1 ...
  • invalid csrf token

    2021-01-07 04:30:13
    在插件<code>egg-security获得的<code>token为空,造成验证失败。 是本地模式,<code>npm run dev中测试的。 应该怎么处理,让验证通过。</p><p>该提问来源于开源项目:alibaba/beidou</p>...
  • 小程序access_token耗尽问题

    千次阅读 2019-05-19 19:41:59
    概述 前几天,产品经理紧急打我电话...啥都没有,简直醉了,只能用tail -f xxxx.log命令,看看具体的报错堆栈,发现是空指针错误,仔细看了一下代码,当access_token为空的时候,会走入到一段特有的逻辑,但是这段...
  • 楼主做项目,判断token是否为空为空则跳回登录页。但是失效了。无论token是否为空,都判断token为空,代码如下: if (token === 'null' || token === ' ') { console.log('失败:' + token) next('/') } ...
  • Spring Boot Feign服务调用之间带token

    万次阅读 2018-08-24 17:40:58
    Feign服务调服务就不多做介绍了,值得提醒的是,Feign服务调服务传递数据的时候,比如某用户服务是需要带token验证的,而调用那个用户服务的时候报错,提示token为空,是因为Feign请求的时候没有带上token ...
  • postman发送带有token的接口测试

    千次阅读 2020-03-20 10:07:22
    value为空 2.登陆接口返回后获得token(在tests中写入设置token参数值的代码) 3.发送请求后,环境变量token中有值了,就是刚刚登陆返回的值 4…当调用其他需要token参数的接口时,就可以直接引用设置好变量{{token}...
  • .net Core Jwt登录验证刷新Token

    千次阅读 2019-07-18 17:10:11
    使用 jwt做登录验证的时候,token的过期...例如设置token失效时间20分钟, 那么只要用户在20分钟之内没有访问后台接口,token将失效。 代码只是个范例,不严谨。小伙伴们自己修改吧!别报引用哦~~~ public c...
  • 以下写入到文件的示例 fs.writeFile('access_token.txt', JSON.stringify(token), callback); }); 只要建个空白文件 access_token.txt 就可以了吗? 首先得把token写入进去吧,后面的...
  • boost::token_compress_on

    2019-08-11 21:42:48
    对于场景:string s = "123456",用"3","4"切分,默认情况下(boost::token_compress_off),切分结果12,,56,注意,这里的不是空格。而是"3","4"之间的。如果不想要这个,指定boost::token_compress_...
  • 问题描述: 我做的项目,是从别人的项目中跳过来的,所以自己的项目中,没有登录功能。...第二个问题是首次别的域名跳到我的页面时,页面的数据为空,然后刷新页面恢复正常, 如果是切换其他的账号
  • 由于项目OAuth2采用了多种模式,授权码模式为第三方系统接入,密码模式用于用户登录,Client模式用于服务间调用, ... 通过调试发现资源服务从授权服务拿到的authrities字段一直为空, StackOverFlow说低版本(项目...
  • 可是这样后,a.jsp源码中[color=red]${org.apache.struts.taglib.html.TOKEN}为空[/color]传不过去,如果用js传该怎么写呢? [color=red]修改Action,然后 提交当前Form吧; [/color] 如果这样,有需要怎么改呢?谢谢...
  • 第三方聊天融云Token失效问题

    千次阅读 2018-09-01 10:00:10
    No.1 ... No.2 在融云官网查看聊天权限是否开启,融云key是否一致 ...连接融云时传的融云Token是否为空(本人两次出现这个问题,本地保存数据的问题) No.5 那可能就不是你的问题了。祝你好运...
  • 今天遇到了一个很怪的问题,在vue-cli+webpack的项目中,刷新特定页面后页面会变空白,报错index.html文件中Unexpected token <。 怪点一是开发环境没有问题,只有生产环境有问题,怪点二是只有一个页面有问题...
  • 但是你要是获取的数值为空 bool(false) 这是由于微信公众号自带的证书验证问题造成的,所以在代码中加入一下 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 就可以跳过验证 curl_setopt($ch, CURLOPT_SSL...
  • access_token等都是的。不知道怎么设置回调地址? 之前测试过将回调地址设置好之后,SSO没有问题。但是App Store里的App的新浪微博就登录不了了。所以想问一下有没有两全其美的解决方案? 多谢...
  • 写单元测试的时候,用Mock模拟请求oauth2的token时,发现一直都为空;同时,带token头的校验也不被Security拦截了,这引起了我的疑惑 核心 根据不被拦截,不难发现,其实Oauth2/Security的拦截器没有被加载进单元...
  • 方法的参数没有获取到,从而导致参数为空而报错2,检查参数引号是否为正确,是否忘了闭合。3,如果参数中的数是从数据库中获取的,请检查数据库中的数据是否存在空格或者空行,就像我今天添加数据时是直接从网页上...
  • 在使用dialog或者popupwindow时经常会出现以下错误导致应用crash,即获取的token为空,原因是使用的控件需要绑定Activity的context,而控件生成时Activity还没有完成加载,因此会出现以下错误。 产生错误的情景...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 203
精华内容 81
关键字:

token为空了