Token导航 LogoToken导航

Agent Skill · 运维

user-authentication-system(用户认证系统)

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

user-authentication-system 是运维类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为需要联网;许可证为 MIT-0,第三方扫描有提醒项,按安装量在运维类的 954 个 Skill 里排第 179。

总安装 20,871周安装 861GitHub Stars 公开资料未说明下载 6,819核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
0.1.1

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:user-authentication-system(用户认证系统)
来源仓库:https://github.com/satoshistackalotto/user-authentication-system
安装命令:
openclaw skills install user-authentication-system
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install user-authentication-system

这个 Skill 是做什么的

运维类 Skill 处理部署、监控、日志和云资源,多数需要较高的执行权限。

希腊会计师事务所基于角色的访问控制。登录、角色层次结构、每个客户端权限、会话管理、审核日志记录。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install user-authentication-system;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

user-authentication-system 怎么安装?

在终端执行 openclaw skills install user-authentication-system。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

user-authentication-system 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

user-authentication-system 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

user-authentication-system 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

user-authentication-system 用的人多吗?

公开数据是累计安装 20,871 次,近一周安装 861 次,下载 6,819 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

user-authentication-system 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。

先想清楚的地方

  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理运维类任务、又不想每次都手写提示词的人。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

运维类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
docker-essentials

Docker 基础 · OpenClaw

1,005,15130接触敏感数据MIT-0通过
playwright-scraper-skill

Playwright scraper 技能 · OpenClaw

923,55754接触敏感数据MIT-0有提醒
moltguard

moltguard 搜索 · OpenClaw

825,096110接触敏感数据MIT-0通过
finance-news

财经新闻 · OpenClaw

275,51210需要联网MIT-0有提醒
security-monitor

安全监视器 · OpenClaw

224,1695需要联网MIT-0有提醒
user-authentication-system

用户认证系统 · 本页

20,871—需要联网MIT-0有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
user-authentication-system
description
Role-based access control for Greek accounting firms. Login, role hierarchy, per-client permissions, session management, audit logging.
version
1.0.0
author
openclaw-greek-accounting
homepage
https://github.com/satoshistackalotto/openclaw-greek-accounting
tags
["greek", "accounting", "authentication", "rbac", "security"]
metadata
{"openclaw": {"requires": {"bins": ["jq", "openssl", "openclaw"], "env": ["OPENCLAW_DATA_DIR"]}, "notes": "Manages local user accounts and role-based access. Credentials are stored as salted SHA-256 hashes in OPENCLAW_DATA_DIR/auth/. 2FA uses SHA-256 TOTP. No external auth services — fully local.", "path_prefix": "/data/ in examples refers to $OPENCLAW_DATA_DIR (default: /data/)"}}

User Authentication System

This skill provides a complete authentication and authorization system for Greek accounting firm operations through OpenClaw. It manages user identities, role-based permissions, per-client access controls, and session security for multi-user accounting environments.

Setup

export OPENCLAW_DATA_DIR="/data"
which jq openssl || sudo apt install jq openssl
mkdir -p $OPENCLAW_DATA_DIR/auth
chmod 700 $OPENCLAW_DATA_DIR/auth

No external auth services. User credentials are stored as salted SHA-256 hashes locally. 2FA uses SHA-256 TOTP generated by openssl.

Core Philosophy

  • Role-Based Access: Hierarchical permissions matching real accounting firm structures
  • Per-Client Authorization: Granular control over which users access which client data
  • Session Security: Secure session management with timeout and device tracking
  • Audit Integration: Every authentication and authorization event logged
  • OpenClaw Artifact Ready: File-based auth suitable for OpenClaw deployment

OpenClaw Commands

User Management

openclaw auth user-create --username "maria.g" --role assistant --full-name "Maria Georgiou" --email "maria@firm.gr"
openclaw auth user-update --username "maria.g" --role accountant --effective-date 2026-03-01
openclaw auth user-deactivate --username "maria.g" --reason "resignation" --revoke-sessions
openclaw auth user-list --active --role assistant --format table
openclaw auth password-reset --username "maria.g" --send-reset-link
openclaw auth password-policy --min-length 12 --require-special --max-age-days 90

Role & Permission Management

openclaw auth role-list --include-permissions
openclaw auth role-create --name "tax_specialist" --base-role accountant --add-permissions "tax_filing,tax_optimization"
openclaw auth assign-clients --username "maria.g" --clients EL123456789,EL987654321
openclaw auth assign-clients --username "maria.g" --all-clients
openclaw auth check-access --username "maria.g" --client EL123456789 --action "view_financials"
openclaw auth access-matrix --all-users --all-clients --format xlsx

Security & Audit

openclaw auth security-log --last-24h --include-failures
openclaw auth failed-logins --threshold 3 --lockout-duration 30m
openclaw auth audit-report --user "maria.g" --period last-30-days
openclaw auth audit-report --client EL123456789 --who-accessed --period last-week
openclaw auth 2fa-enable --username "maria.g" --method totp
openclaw auth sessions-list --active --format table
openclaw auth session-revoke --username "maria.g" --all-devices

File System Architecture

Auth_File_Structure:
  user_data:
    - /data/auth/users/{username}/profile.json
    - /data/auth/users/{username}/credentials.json
    - /data/auth/users/{username}/permissions.json
    - /data/auth/users/{username}/sessions/
    - /data/auth/users/{username}/2fa/

  role_definitions:
    - /data/auth/roles/senior_accountant.json
    - /data/auth/roles/accountant.json
    - /data/auth/roles/assistant.json
    - /data/auth/roles/viewer.json
    - /data/auth/roles/custom/

  access_control:
    - /data/auth/access/client_assignments.json
    - /data/auth/access/policies.json
    - /data/auth/access/ip_whitelist.json

  security_logs:
    - /data/auth/logs/logins/
    - /data/auth/logs/access/
    - /data/auth/logs/admin/
    - /data/auth/logs/security/

Role Hierarchy & Permissions

Role Definitions

Roles:
  senior_accountant:
    description: "Senior accountant - full system access"
    level: 4
    inherits: "accountant"
    permissions:
      - all_client_access
      - user_management
      - role_assignment
      - system_configuration
      - data_export_all
      - compliance_override
      - audit_log_access
      - gdpr_operations
      - billing_management
      - skill_configuration
    client_access: "all"

  accountant:
    description: "Accountant - broad access to assigned clients"
    level: 3
    inherits: "assistant"
    permissions:
      - client_data_full_access
      - tax_filing_submit
      - tax_optimization
      - compliance_management
      - financial_reporting
      - efka_submissions
      - banking_reconciliation
      - deadline_management
      - client_communication
    client_access: "assigned_only"
    restrictions:
      - cannot_manage_users
      - cannot_change_system_config

  assistant:
    description: "Accountant assistant - operational access"
    level: 2
    inherits: "viewer"
    permissions:
      - document_upload
      - document_processing
      - data_entry
      - email_processing
      - dashboard_access
      - basic_reporting
      - client_data_edit_basic
      - alert_acknowledgement
      - ocr_processing
    client_access: "assigned_only"
    restrictions:
      - cannot_submit_tax_filings
      - cannot_export_sensitive_data
      - cannot_modify_financial_records

  viewer:
    description: "Read-only access to assigned client data"
    level: 1
    permissions:
      - dashboard_view
      - client_data_view
      - report_view
      - deadline_view
      - document_view
    client_access: "assigned_only"
    restrictions:
      - read_only
      - no_data_modification
      - no_data_export

Permission Matrix

Permission_Matrix:
  view_dashboard: "viewer"
  configure_dashboard: "accountant"
  view_client_profile: "viewer"
  edit_client_profile: "assistant"
  create_client: "accountant"
  delete_client: "senior_accountant"
  export_client_data: "accountant"
  gdpr_operations: "senior_accountant"
  view_documents: "viewer"
  upload_documents: "assistant"
  process_documents: "assistant"
  delete_documents: "accountant"
  view_financials: "viewer"
  enter_financial_data: "assistant"
  modify_financial_records: "accountant"
  submit_tax_filings: "accountant"
  view_compliance_status: "viewer"
  manage_compliance: "accountant"
  override_compliance: "senior_accountant"
  view_employee_data: "viewer"
  manage_employees: "accountant"
  submit_efka: "accountant"
  view_transactions: "viewer"
  reconcile_transactions: "assistant"
  configure_banking: "accountant"
  manage_users: "senior_accountant"
  manage_roles: "senior_accountant"
  view_audit_logs: "senior_accountant"
  system_configuration: "senior_accountant"

Authentication Engine

Core Authentication

class AuthenticationEngine:
    """Handles user authentication, sessions, and credential management."""

    def __init__(self):
        self.session_timeout = 30 * 60  # 30 minutes
        self.idle_timeout = 15 * 60     # 15 minutes
        self.max_failed_attempts = 5
        self.lockout_duration = 30 * 60  # 30 minutes

    def authenticate(self, username, password, device_info=None):
        """Authenticate user and create session."""
        if self.is_account_locked(username):
            self.log_auth_event(username, 'login_blocked', 'account_locked')
            return {'success': False, 'error': 'Account is locked. Contact administrator.'}

        user = self.load_user(username)
        if not user:
            self.log_auth_event(username, 'login_failed', 'user_not_found')
            return {'success': False, 'error': 'Invalid credentials'}

        if not self.verify_password(password, user['password_hash']):
            self.record_failed_attempt(username)
            self.log_auth_event(username, 'login_failed', 'wrong_password')
            return {'success': False, 'error': 'Invalid credentials'}

        if user['status'] != 'active':
            self.log_auth_event(username, 'login_failed', f'account_{user["status"]}')
            return {'success': False, 'error': 'Account is not active'}

        if user.get('2fa_enabled', False):
            return {'success': False, 'requires_2fa': True,
                    'session_pending': self.create_pending_session(username)}

        session = self.create_session(username, device_info)
        self.clear_failed_attempts(username)
        self.log_auth_event(username, 'login_success', device_info=device_info)
        return {'success': True, 'session': session, 'user': self.get_user_summary(username)}

    def create_session(self, username, device_info=None):
        """Create a new authenticated session.
        
        Security: The raw session token is returned to the user exactly once.
        Only the salted SHA-256 hash is stored on disk. Validation compares
        the hash of the incoming token against the stored hash.
        """
        raw_token = generate_secure_token(64)
        token_hash = hash_session_token(raw_token)  # SHA-256 salted hash
        session = {
            'session_id': token_hash,
            'username': username,
            'created_at': current_timestamp(),
            'expires_at': current_timestamp() + self.session_timeout,
            'last_activity': current_timestamp(),
            'device_info': device_info,
            'ip_address': get_request_ip(),
            'role': self.get_user_role(username),
            'client_access': self.get_user_client_access(username)
        }
        session_path = f"/data/auth/users/{username}/sessions/{token_hash}.json"
        write_json(session_path, session)
        # Return raw token to user — this is the only time it exists in cleartext
        session['bearer_token'] = raw_token
        return session

    def validate_session(self, session_id):
        """Validate an existing session."""
        session = self.find_session(session_id)
        if not session:
            return {'valid': False, 'reason': 'session_not_found'}
        if current_timestamp() > session['expires_at']:
            self.destroy_session(session_id)
            return {'valid': False, 'reason': 'session_expired'}
        if current_timestamp() - session['last_activity'] > self.idle_timeout:
            self.destroy_session(session_id)
            return {'valid': False, 'reason': 'idle_timeout'}
        session['last_activity'] = current_timestamp()
        self.update_session(session)
        return {'valid': True, 'session': session}

    def hash_password(self, password):
        """Hash password using bcrypt with salt."""
        return bcrypt_hash(password, rounds=12)

    def validate_password_strength(self, password):
        """Check password meets policy requirements."""
        errors = []
        if len(password) < 12:
            errors.append("Password must be at least 12 characters")
        if not any(c.isupper() for c in password):
            errors.append("Must contain uppercase letter")
        if not any(c.islower() for c in password):
            errors.append("Must contain lowercase letter")
        if not any(c.isdigit() for c in password):
            errors.append("Must contain digit")
        if not any(c in '!@#$%^&*()_+-=' for c in password):
            errors.append("Must contain special character")
        return {'valid': len(errors) == 0, 'errors': errors}

Authorization Engine

class AuthorizationEngine:
    """Handles permission checks and access control decisions."""

    def __init__(self):
        self.roles = self.load_roles()
        self.access_matrix = self.load_access_matrix()

    def check_permission(self, session, action, client_vat=None):
        """Check if user has permission to perform an action."""
        username = session['username']
        user_role = session['role']

        required_role = self.access_matrix.get(action)
        if not required_role:
            self.log_authorization(username, action, client_vat, 'denied', 'unknown_action')
            return {'allowed': False, 'reason': f'Unknown action: {action}'}

        user_level = self.roles[user_role]['level']
        required_level = self.roles[required_role]['level']

        if user_level < required_level:
            self.log_authorization(username, action, client_vat, 'denied', 'insufficient_role')
            return {'allowed': False,
                    'reason': f'Requires {required_role} role (you have {user_role})'}

        # Check client-specific access
        if client_vat:
            client_access = session.get('client_access', [])
            if 'all' not in client_access and client_vat not in client_access:
                self.log_authorization(username, action, client_vat, 'denied', 'no_client_access')
                return {'allowed': False,
                        'reason': f'Not authorized for client {AFM}'}

        self.log_authorization(username, action, client_vat, 'allowed')
        return {'allowed': True}

    def resolve_permissions(self, role_name):
        """Resolve all permissions including inherited ones."""
        role = self.roles.get(role_name, {})
        permissions = set(role.get('permissions', []))
        parent = role.get('inherits')
        if parent:
            permissions.update(self.resolve_permissions(parent))
        return permissions

    def get_accessible_clients(self, username):
        """Get list of clients this user can access."""
        assignments = read_json("/data/auth/access/client_assignments.json")
        user_entry = assignments.get(username, {})
        if user_entry.get('all_clients', False):
            return {'type': 'all', 'clients': 'all'}
        return {'type': 'specific', 'clients': user_entry.get('clients', [])}

User Management

class UserManager:
    """Manages user lifecycle operations."""

    def __init__(self):
        self.auth_engine = AuthenticationEngine()
        self.authz_engine = AuthorizationEngine()

    def create_user(self, admin_session, user_data):
        """Create a new user account."""
        # Verify admin has permission
        perm_check = self.authz_engine.check_permission(admin_session, 'manage_users')
        if not perm_check['allowed']:
            return {'success': False, 'error': perm_check['reason']}

        username = user_data['username']

        # Check for duplicate
        if self.user_exists(username):
            return {'success': False, 'error': f'Username {username} already exists'}

        # Validate role
        if user_data['role'] not in self.authz_engine.roles:
            return {'success': False, 'error': f'Invalid role: {user_data["role"]}'}

        # Create user profile
        profile = {
            'username': username,
            'full_name': user_data['full_name'],
            'email': user_data.get('email'),
            'role': user_data['role'],
            'status': 'active',
            'created_at': current_timestamp(),
            'created_by': admin_session['username'],
            'password_change_required': True,
            '2fa_enabled': False
        }

        # Generate temporary password
        temp_password = generate_secure_password()
        credentials = {
            'password_hash': self.auth_engine.hash_password(temp_password),
            'password_set_at': current_timestamp(),
            'password_change_required': True
        }

        # Create user directory and files
        user_dir = f"/data/auth/users/{username}"
        create_directory(user_dir)
        create_directory(f"{user_dir}/sessions")
        create_directory(f"{user_dir}/2fa")
        write_json(f"{user_dir}/profile.json", profile)
        write_json(f"{user_dir}/credentials.json", credentials)
        write_json(f"{user_dir}/permissions.json", {'role': user_data['role'], 'custom': []})

        # Audit log
        self.log_admin_action(admin_session['username'], 'user_created', {
            'new_user': username, 'role': user_data['role']
        })

        return {
            'success': True,
            'username': username,
            'temporary_password': temp_password,
            'message': f'User {username} created with role {user_data["role"]}. '
                       f'Password change required on first login.'
        }

    def assign_clients(self, admin_session, username, client_vats):
        """Assign client access to a user."""
        perm_check = self.authz_engine.check_permission(admin_session, 'manage_users')
        if not perm_check['allowed']:
            return {'success': False, 'error': perm_check['reason']}

        assignments_path = "/data/auth/access/client_assignments.json"
        assignments = read_json(assignments_path) if file_exists(assignments_path) else {}

        if client_vats == 'all':
            assignments[username] = {'all_clients': True, 'clients': []}
        else:
            current = assignments.get(username, {'all_clients': False, 'clients': []})
            current['clients'] = list(set(current.get('clients', []) + client_vats))
            assignments[username] = current

        write_json(assignments_path, assignments)

        self.log_admin_action(admin_session['username'], 'clients_assigned', {
            'user': username, 'clients': client_vats
        })

        return {'success': True, 'username': username, 'client_access': assignments[username]}

Security Features

File System Permissions (Production Hardening)

The /data/auth/ directory contains sensitive credential and session data. In production, OS-level file permissions must be hardened:

# Restrict the entire auth directory
chmod 700 /data/auth/
chown -R openclaw:openclaw /data/auth/

# Credential files must be read-only to the service user
chmod 600 /data/auth/users/*/credentials.json

# Session files
chmod 600 /data/auth/users/*/sessions/*.json

# Role definitions (read by all skills for auth checks, writable only by admin)
chmod 644 /data/auth/roles/*.json

# Audit logs (append-only in production if OS supports it)
chmod 600 /data/auth/logs/**/*.json

Note: The OpenClaw agent and all skills share the same file system context. Without OS-level permission restrictions, any skill could read credential hashes. These permissions ensure that only the authentication skill's process can access sensitive auth data.

Account Lockout

Lockout_Policy:
  max_failed_attempts: 5
  lockout_duration: "30 minutes"
  lockout_escalation:
    - "5 failures: 30 minute lockout"
    - "10 failures: 2 hour lockout"
    - "15 failures: account disabled, admin notification"
  notification: "email admin on 3+ consecutive failures"

Two-Factor Authentication

2FA_Configuration:
  methods: ["totp"]
  mandatory_for: ["senior_accountant"]
  optional_for: ["accountant", "assistant"]
  recovery_codes: 10
  totp_settings:
    algorithm: "SHA256"
    digits: 6
    period: 30

Password Policy

Password_Policy:
  min_length: 12
  require_uppercase: true
  require_lowercase: true
  require_digit: true
  require_special: true
  max_age_days: 90
  history_count: 5
  common_password_check: true

IP & Device Security

Security_Controls:
  ip_whitelist:
    enabled: true
    allowed_ranges: ["office_ip_range"]
    action_on_violation: "block_and_alert"

  device_tracking:
    track_devices: true
    alert_new_device: true
    max_concurrent_sessions: 3

  session_controls:
    absolute_timeout: "8 hours"
    idle_timeout: "15 minutes"
    single_session_per_device: true

Integration with Other Skills

Skill_Integration:
  dashboard_greek_accounting:
    provides: ["user_session", "role_permissions", "accessible_clients"]
    enforces: "dashboard view permissions per user role"

  client_data_management:
    provides: ["access_decisions", "user_identity"]
    enforces: "per-client data access based on user assignments"
    integration: "authorization check before every data operation"

  greek_compliance_aade:
    enforces: "only accountant+ can submit filings"

  efka_api_integration:
    enforces: "only accountant+ can submit EFKA data"

  all_skills:
    provides: "user context for audit trail entries"
    enforces: "role-based action restrictions across all operations"

Audit & Compliance Reporting

Audit Log Structure

Audit_Events:
  authentication:
    - login_success
    - login_failed
    - login_blocked
    - logout
    - session_expired
    - session_revoked
    - 2fa_success
    - 2fa_failed
    - password_changed
    - password_reset

  authorization:
    - access_granted
    - access_denied
    - client_access_checked
    - permission_checked

  administration:
    - user_created
    - user_updated
    - user_deactivated
    - role_changed
    - clients_assigned
    - clients_revoked
    - policy_changed

Audit_Entry_Format:
  timestamp: "ISO 8601 with timezone"
  event_type: "category.action"
  username: "acting user"
  target: "affected resource"
  client_vat: "if client-specific"
  result: "success/failure"
  details: "additional context"
  ip_address: "source IP"
  session_id: "active session"

Success Metrics

A successful authentication system deployment should achieve:

  • ✅ Secure Authentication: bcrypt password hashing, optional 2FA, session management
  • ✅ Role Hierarchy: Four-level role system matching accounting firm structures
  • ✅ Per-Client Access: Granular client data access assignment per user
  • ✅ Session Security: Timeout, idle detection, concurrent session limits
  • ✅ Complete Audit Trail: Every auth/authz event logged with context
  • ✅ Account Protection: Lockout policy, password requirements, brute-force prevention
  • ✅ Cross-Skill Enforcement: Authorization integrated into all data operations
  • ✅ Admin Tools: User management, access matrix, security reporting
  • ✅ GDPR Compatible: Access controls support data protection requirements
  • ✅ Scalable: Handle 50+ users across 500+ clients

Remember: The authentication system is the security foundation for the entire Greek accounting platform. Every data access must pass through authorization checks, and every action must leave an audit trail.

平台分布

OpenClaw

91.06%
按下载量换算6,209

安全审计

VirusTotal

通过

ClawScan

可疑

Static analysis

未展示

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills